1. 程式人生 > >[BZOJ]3060: [Poi2012]Tour de Byteotia

[BZOJ]3060: [Poi2012]Tour de Byteotia

忽略 span main 需要 inpu fin com etc 刪掉

題解:首先我們忽略<=k這個條件 可以得出每形成一個環就需要刪掉一條邊 那麽並查集搞一下 就可以得出答案 那麽對於k的限制 我們先把兩點都大於k的邊處理掉 然後剩下的繼續並查集搞一下 就完了

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define link(x) for(edge *j=h[x];j;j=j->next)
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=1e6+10;
const double eps=1e-8;
#define ll long long
using namespace std;
struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-‘0‘,ch=getchar();
    return x*f;
}


int f[MAXN];
int find1(int x){
    if(f[x]==x)return x;
    return f[x]=find1(f[x]);
}

typedef struct node{
    int u,v;
}node;
node d[MAXN<<1];

int main(){
    int n=read(),m=read(),k=read();
    inc(i,1,n)f[i]=i;
    int u,v;int ans=0,cnt=0;
    inc(i,1,m){
	u=read();v=read();
	if(u>k&&v>k){
	    int t1=find1(u);int t2=find1(v);
	    if(t1!=t2)f[t1]=t2;
	}
	else d[++cnt]=(node){u,v};
    }
    inc(i,1,cnt){
	int t1=find1(d[i].u);int t2=find1(d[i].v);
	if(t1==t2)ans++;
	else f[t1]=t2;
    }
    printf("%d\n",ans);
    return 0;
}

  

3060: [Poi2012]Tour de Byteotia

Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 388 Solved: 254
[Submit][Status][Discuss]

Description

給定一個n個點m條邊的無向圖,問最少刪掉多少條邊能使得編號小於等於k的點都不在環上。

Input

第一行三個整數nmk; 接下來m行每行兩個整數aibi,表示aibi之間有一條無向邊。

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

[BZOJ]3060: [Poi2012]Tour de Byteotia