3060: [Poi2012]Tour de Byteotia
Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 279 Solved: 178
[ Submit][ Status][ Discuss]
Description
给定一个n个点m条边的无向图,问最少删掉多少条边能使得编号小于等于k的点都不在环上。
Input
第一行三个整数n,m,k;
接下来m行每行两个整数ai,bi,表示ai和bi之间有一条无向边。
Output
一个整数,表示最少的删边数量。
Sample Input
11 13 5
1 2
1 3
1 5
3 5
2 8
4 11
7 11
6 10
6 9
2 3
8 9
5 9
9 10
Sample Output
3
HINT
数据范围:
对于100%的数据满足:1 ≤ n ≤ 1,000,000,1 ≤ m ≤ 2,000,000,1 ≤ k ≤ n。
Source
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
const int maxn = 1E6 + 10;
struct E{
int x,y; E(){}
E(int x,int y): x(x),y(y){}
}edgs[maxn*2];
int n,m,k,Ans,fa[maxn];
int getint()
{
char ch = getchar(); int ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret*10 + ch - '0',ch = getchar();
return ret;
}
int getfa(int x) {return x == fa[x] ? x : fa[x] = getfa(fa[x]);}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
n = getint(); m = getint(); k = getint();
for (int i = 1; i <= n; i++) fa[i] = i;
for (int i = 1; i <= m; i++)
{
int x = getint(),y = getint(); edgs[i] = E(x,y);
if (x > k && y > k)
{
int fx = getfa(x),fy = getfa(y);
if (fx != fy) fa[fx] = fy;
}
}
for (int i = 1; i <= m; i++)
{
if (edgs[i].x > k && edgs[i].y > k) continue;
if (edgs[i].x <= k && edgs[i].y <= k) continue;
int fx = getfa(edgs[i].x),fy = getfa(edgs[i].y);
if (fx != fy) fa[fx] = fy; else ++Ans;
}
for (int i = 1; i <= m; i++)
if (edgs[i].x <= k && edgs[i].y <= k)
{
int fx = getfa(edgs[i].x),fy = getfa(edgs[i].y);
if (fx != fy) fa[fx] = fy; else ++Ans;
}
cout << Ans;
return 0;
}