封锁阳光大学
【题目描述】
阳光大学校园是一张由N个点构成的无向图,N个点之间由M条道路连接。每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,人们就无法在这些道路上逛街了。当两只河蟹封锁了相邻的两个点时,他们会发生冲突。
询问最少需要多少只河蟹,可以封锁所有道路并且不发生冲突。
【输入描述】
第一行:两个整数N、M;
接下来M行:每行两个整数A、B,表示点A到点B之间有道路相连。
【输出描述】
输出仅一行,如果河蟹无法封锁所有道路,则输出“Impossible”,否则输出一个整数,表示最少需要多少只河蟹。
【输入样例】
样例1:
3 3
1 2
1 3
2 3
样例2:
3 2
1 2
2 3
【输出样例】
样例1:
Impossible
样例2:
1
【数据范围及提示】
1 <= N <= 10000,1 <= M <= 100000,任意两点之间最多有一条道路。
源代码: #include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; int n,m,N,M,ans(0),f[10001],i[10001][300]; void DFS(int T) //二分图染色同理。 { for (int a=1;a<=i[T][0];a++) //遍历连接。 { if (f[i[T][a]]==f[T]) //父节点重复。 { printf("Impossible"); exit(0); } if (!f[i[T][a]]) //没有父节点。 { f[i[T][a]]=3-f[T]; if (f[i[T][a]]==1) N++; else M++; DFS(i[T][a]); } } } int main() //题目数据水,深搜竟AC。 { scanf("%d%d",&n,&m); for (int a=1;a<=m;a++) { int t1,t2; scanf("%d%d",&t1,&t2); i[t1][++i[t1][0]]=t2; //i[t1][0]存储直连边数,同理于下。 i[t2][++i[t2][0]]=t1; //i[t2][Num]表示t2的第Num条边连接着哪个点。 } for (int a=1;a<=n;a++) if (!f[a]) { f[a]=N=1; M=0; DFS(a); ans+=min(N,M); } printf("%d",ans); return 0; }