BZOJ 1116: [POI2008]CLO [连通分量]

Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 你要把其中一些road变成单向边使得:每个town都有且只有一个入度 


 

和上题一样...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=1e5+5, M=2e5+5;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

int n, m, u, v;
struct edge{int v, ne;} e[M<<1];
int cnt=1, h[N];
inline void ins(int u, int v) {
    e[++cnt]=(edge){v, h[u]}; h[u]=cnt;
    e[++cnt]=(edge){u, h[v]}; h[v]=cnt;
}
int vis[N], q[N], p, circle, flag[N];
int ve[M<<1];
void dfs(int u) {
    vis[u]=1; q[++p]=u;
    for(int i=h[u];i;i=e[i].ne) if(!ve[i]){
        ve[i] = ve[i^1] = 1;
        if(!vis[e[i].v]) dfs(e[i].v);
        else circle=1;
    }
}
int main() {
    freopen("in","r",stdin);
    n=read(); m=read();
    for(int i=1; i<=m; i++) u=read(), v=read(), ins(u, v);
    for(int i=1; i<=n; i++) if(!vis[i]) {
        p=0; circle=0; dfs(i);
        int mx=0;
        for(int i=1; i<=p; i++) {
            if(flag[q[i]]) circle = 1;
            else flag[q[i]] = 1;
            mx = max(mx, q[i]);
        } 
        if(!circle) flag[mx] = 0;
    }
    int ans = 0;
    while(flag[ans+1]) ans++;
    puts(ans==n ? "TAK" : "NIE");
}

 

posted @ 2017-03-21 11:42  Candy?  阅读(159)  评论(0编辑  收藏  举报