分析:
地图上有若干个城镇,城镇都可以看作点,然后给出哪些城镇之间是直接相连的。要解决的是整幅图的连通性问题。比如两个点,判断它们是否连通,或者整幅图共有几个连通分支,就是被分成多少个互相独立的块。因此这个题实质就是求有几个连通分支;如果是1个,则整幅图都连起来了;如果是2个,只要再修1条路,在两个分支中各选一个点,连起来,这样所有点就连起来了;3个连通分支,则只需再修两条。。。。。。,这样就可以使用并查集很好的解决了。
#include<iostream> using namespace std; int p[1001]; bool Init(int n) //一开始指向自己 { for(int i=0;i<=n;i++) p[i]=i; return true; } int Find(int x) //找到根节点 { int r,i,j; r=x; while(r!=p[r]) r=p[r]; //路径压缩准备,找到根节点 i=x; while(i!=p[i]) { j=p[i]; p[i]=r; i=j; } return i; //返回根节点 } bool Merge(int x,int y) //返回是否需要合并 { int tx,ty; tx=Find(x); ty=Find(y); if(tx==ty) return false; p[tx]=ty; return true; } int main() { int N,M,i,a,b,total; while(scanf("%d",&N)) { if(N==0) break; scanf("%d",&M); total=N-1; //一开始都没连通,最少需要修N-1条路才能把N个城市连接起来 Init(N ); for(i=0;i<M;i++) { scanf("%d%d",&a,&b); if(Find(a)!=Find(b)) //如果不连通,就把它连起来,还需修路就减一 { Merge(Find(a),Find(b)); total--; }
<span style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: rgb(238, 238, 238);"> //如果两点已经连通,那么这条路只是在图上增加了一个环,对连通性没有影响,忽略。</span> } printf("%d\n",total); } return 0; }
时间: 2024-10-09 02:13:23