SJTU SCPC Monthly Oct.2013 Problem A. dream
【题目描述】
A梦见一个非常奇妙的事情。他看到了一张无向图,然后他从这张无向图上删去了若干(非负)数量条边,使得剩下图中任意两点仍然连通,并且再删去任何一条边,都会使得图不连通。
第二天他醒来的时候,A只记得无向图最初的模样,却不记得最后的情景。所以他希望你能够为他判断,他是否唯一的删去若干条边,使得剩下的图满足要求。
【输入格式】
输入入的第一行包含一个整数T,表示数据的组数。
接下来T组数据,每组的第一行包括两个整数n和m,表示无向图中点和边的个数。接下来m行,每行有两个1到n之间的整数表示无向图的两个顶点。
数据中可能会有重边和自环。
【输出格式】
输出T行,每行包括一个字符串。如果能唯一删去若干条边使得图满足要求,则输出"Yes",如果可能有多种情况,输出"No"。如果不可能通过删边满足要求,则输出"Nani?!"。
【样例输入】
3
1 0
2 0
3 3
1 2
2 3
3 1
【样例输出】
Yes
Nani?!
No
【数据范围】
n不超过100000,m不超过200000。
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <map> 3 #include <queue> 4 #include <vector> 5 #include <string> 6 #include <cstdio> 7 #include <cstring> 8 #include <iostream> 9 #include <algorithm> 10 using namespace std; 11 #define maxn 1000005 12 #define ll long long 13 #define INF 0x7fffffff 14 int vis[maxn]; 15 int sum[maxn]; 16 int n, m; 17 int find(int x){ 18 if (x != sum[x])sum[x] = find(sum[x]); 19 return sum[x]; 20 } 21 void search(int x, int y){ 22 int fx = find(x), fy = find(y); 23 if (fx != fy)sum[fy] = fx; 24 } 25 int main(){ 26 int cas = 1; 27 int t; 28 scanf("%d", &t); 29 while (t--){ 30 scanf("%d%d", &n, &m); 31 for (int i = 0; i < n; i++)sum[i] = i; 32 int k = 0; 33 for (int i = 0; i < m; i++){ 34 int a, b; 35 scanf("%d%d", &a, &b); 36 a--; b--; 37 search(a, b); 38 if (a == b)k++; 39 } 40 memset(vis, 0, sizeof vis); 41 int x; 42 for (int i = 0; i < n; i++){ 43 x = find(i); 44 vis[x]++; 45 } 46 if (vis[x] != n){printf("Nani?!\n"); continue;} 47 if (m + 1 == n||m==n&&k==1)printf("Yes\n"); 48 else printf("No\n"); 49 //printf("Case %d: ",cas++); 50 } 51 return 0; 52 }
浙公网安备 33010602011771号