codeforce 659E New Reform

来源:互联网 发布:剑三官方道长捏脸数据 编辑:程序博客网 时间:2024/05/16 17:41

原题地址


题意

已知n个点和m条无向边,保证不存在起点终点一样的边和两座城市之间至多一条边直接相连,不保证图连通

现在总统下令改革,把所有无向边改为有向边,要求改后的图上“孤立”的点最少,“孤立”是指没有入边的点,有无出边不影响。

输入边的信息。

输出最少的“孤立”点个数。


题解

在一个连通子图中,只要边数大于等于顶点数,就不会有孤立点,证明凭直觉

注意:上述条件需满足“两座城市之间至多一条边直接相连”这一条件才"直觉"上成立

否则会怎么样呢,应该也不会怎么样大笑,还是没有问题吧……

用并查集维护每个集合的点数,边数,最后遍历所有点,记录一下就好了吧……


#include<bits/stdc++.h>using namespace std;const int maxn=1e5;int par[maxn+5];int rank[maxn+5];int d[maxn+5]; //点数 int rnum[maxn+5]; //边数 int find(int x){return x==par[x]?x:par[x]=find(par[x]);}void unite(int x,int y){int rx=par[x];int ry=par[y];if (rank[rx]>rank[ry]){par[ry]=rx;rnum[rx]+=rnum[ry]+1;d[rx]+=d[ry];}else{par[rx]=ry;rnum[ry]+=rnum[rx]+1;d[ry]+=d[rx];if (rank[rx]==rank[ry]) ++rank[rx];}}int main(void){#ifdef exfreopen ("in.txt","r",stdin);#endifint n,m;int x,y;scanf("%d%d",&n,&m);for (int i=1;i<=n;++i){par[i]=i;rank[i]=1;d[i]=1;rnum[i]=0;}for (int i=1;i<=m;++i){scanf("%d%d",&x,&y);if (find(x)!=find(y)){unite(x,y);}else{++rnum[par[x]];}}int ans=0;for (int i=1;i<=n;++i){if (par[i]==i){if (rnum[i]<d[i]) ++ans;}}printf("%d\n",ans);}




0 0
原创粉丝点击