1. 程式人生 > >Codeforces 1065B Vasya and Isolated Vertices

Codeforces 1065B Vasya and Isolated Vertices

簡單的圖論+思考題,給定n個頂點m條邊(無向圖),而且沒有重邊(重邊:兩個頂點之間有多條邊)和連線同一個頂點的"奇葩邊",現在要求你求兩個數。

第一個數,最小孤立頂點數。

第二個數,最大孤立頂點數。

其中孤立頂點又是這樣定義的,它不與圖中任意其他頂點相連,就像一個孤島一樣。

題意很簡單,先考慮最小孤立頂點數。我們儘可能用最少的邊去連線更多的頂點,顯然一條邊最多連線兩個頂點,所以我們用m條邊最多可以連線2*m個頂點,用2*m和給定的n個頂點作比較即可。

最大孤立頂點比較麻煩,但是也很容易考慮,我們儘可能去新增"冗餘邊"就行,而冗餘邊最多的圖顯然是完全圖(任何兩點之間都有邊相連),我們只需要找到圖中最大的一個子完全圖就行。

但是,雖然題目很簡單,但是我從開始做到最後AC,耗時近1h。

1、一開始求最小孤立頂點數時,考慮了鏈式模型,即m條邊最多連線m+1個頂點。

2、真的是好久不寫程式碼了,寫C程式碼的時候居然連迴圈變數什麼時候自增,break語句的具體用法都忘了。

3、資料範圍爆int,真的坑人。而且迴圈變數也要改成long long。

4、邊數可以為0...!

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <iostream>

using namespace std;

long long n, m;
long long mymin, mymax;

int main() {
	scanf("%lld %lld", &n, &m);
	if (m == 0) {
		printf("%lld %lld\n",n,n);
	}
	else {
		long long maxVertex = m * 2;
		if (maxVertex >= n) {
			mymin = 0;
		}
		else {
			mymin = n - maxVertex;
		}
		if (n*(n - 1) / 2 <= m) {
			mymax = 0;
		}
		else {
			long long i;
			for (i = 1;i <= n - 1;++i) {
				if (i*(i - 1) / 2 == m) {
					break;
				}
			}
			if (i == n) {
				long long j;
				for (j = 1;j <= n - 1;++j) {
					if (j*(j - 1) / 2 > m) {
						break;
					}
				}
				mymax = n - j;
			}
			else {
				mymax = n - i;
			}
		}
		printf("%lld %lld\n", mymin, mymax);
	}
	//system("pause");
	return 0;
}