题意
给定一个$n$个点$m$条边的无向图,问最少删掉多少条边能使得编号小于等于$k$的点都不在环上。
思路
要想让编号小于等于$k$的点都不在环上,那么就最好让所有编号大于$k$的边都在环上。 那么可以用并查集把所有编号大于$k$的边连起来,再判断编号小于等于$k$的边是否在环上即可。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include<bits/stdc++.h> using namespace std; inline int read(){ int res=0,f=1;char ch=getchar();while(ch<'0'ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar();return res*f; } int n,m,k,fa[1000010],ans,x[1000010],y[1000010]; inline int getfa(int x){return fa[x]==x?x:fa[x]=getfa(fa[x]);} inline void merge(int x,int y){ x=getfa(x); y=getfa(y); if(x==y) ; else fa[y]=x; } int main(){ n=read();m=read();k=read(); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++){ x[i]=read();y[i]=read(); if(x[i]>k&&y[i]>k) merge(x[i],y[i]); } for(int i=1;i<=m;i++){ if(x[i]>k&&y[i]>k) continue ; x[i]=getfa(x[i]);y[i]=getfa(y[i]); if(x[i]==y[i]) ans++; else merge(x[i],y[i]); } printf("%d\n",ans); return 0; }
|