bzoj 3060: [Poi2012]Tour de Byteotia 并查集
2017-08-02 11:46
369 查看
题意
给定一个n个点m条边的无向图,问最少删掉多少条边能使得编号小于等于k的点都不在环上。n<=1000000,m<=2000000
分析
我们贪心地想,删边的话,肯定是删掉带关键点的边比删掉不带关键点的边更优。到最后我们会发现,其实不带关键点的边是不会被删掉的。那么我们可以先加入所有不带关键点的边,用并查集维护连通块。
最后加入带关键点的边。若能加入则加入,不能加入则答案+1.
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int N=1000005; int n,m,k,f ; struct edge{int x,y;}e[N*2]; int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int find(int x) { if (f[x]==x) return f[x]; return f[x]=find(f[x]); } int main() { n=read();m=read();k=read(); for (int i=1;i<=m;i++) e[i].x=read(),e[i].y=read(); for (int i=1;i<=n;i++) f[i]=i; int ans=0; for (int i=1;i<=m;i++) if (e[i].x>k&&e[i].y>k) { int x=find(e[i].x),y=find(e[i].y); if (x!=y) f[x]=y; } for (int i=1;i<=m;i++) if (e[i].x<=k||e[i].y<=k) { int x=find(e[i].x),y=find(e[i].y); if (x!=y) f[x]=y; else ans++; } cout<<ans; return 0; }
相关文章推荐
- 【BZOJ3060】[Poi2012]Tour de Byteotia 并查集
- bzoj 3060[Poi2012]Tour de Byteotia 贪心+生成树
- 【BZOJ 3060】【POI2012】Tour de Byteotia/【JZOJ 5442】 荒诞
- 3060: [Poi2012]Tour de Byteotia (并查集)
- 【POI】【POI2012】【Tour de Byteotia】【题解】【并查集】
- [JZOJ5442]【NOIP2017提高A组冲刺11.1】荒诞([BZOJ3060]【POI2012】Tour de Byteotia)
- [BZOJ 3060]POI2012 Tour de Byteotia
- BZOJ3060 [Poi2012]Tour de Byteotia
- Bzoj3060 [Poi2012]Tour de Byteotia
- 3060: [Poi2012]Tour de Byteotia
- bzoj 3060 [Poi2012]Tour de Byteotia 并查集
- [POI 2012]Tour de Byteotia(并查集)
- 【bzoj3060】[Poi2012]Tour de Byteotia 并查集
- 【BZOJ】2802: [Poi2012]Warehouse Store(贪心)
- BZOJ2795/POI2012 A horrible poem
- bzoj2795: [Poi2012]A Horrible Poem
- BZOJ_2795_[Poi2012]A Horrible Poem_hash+暴力
- bzoj 2789: [Poi2012]Letters
- BZOJ2803: [Poi2012]Prefixuffix
- bzoj 2790 [Poi2012]Distance 数学