zoukankan      html  css  js  c++  java
  • BZOJ 1116 POI2008 CLO

    1116: [POI2008]CLO

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1152  Solved: 635
    [Submit][Status][Discuss]

    Description

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

    Input

    第一行输入n m.1 <= n<= 100000,1 <= m <= 200000 下面M行用于描述M条边.

    Output

    TAK或者NIE 常做POI的同学,应该知道这两个单词的了...

    Sample Input

    4 5
    1 2
    2 3
    1 3
    3 4
    1 4

    Sample Output

    TAK

    上图给出了一种连接方式.

    HINT

     

    Source

    并查集水过,方法和游戏那道题一样

    原理是(抄自黄学长的博客)

    这题令我突然想到了scoi游戏
    首先我们可以推出一个性质,当且仅当某一个连通块中没有环存在输出NIE
    于是我们可以用并查集把这题水过。。
    给每个连通块的根一个标记
    合并俩个连通块时只要任意一个连通块带有标记新的连通块就带有标记
    如果一条边的俩个点已经在同一个连通块内了,直接将根打上标记即可
    然后最后扫一遍,如果哪个连通块没有标记的话输出NIE
    否则最后输出TAK
    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0;int 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;
    }
    const int MAXN=1e6+10;
    int f[MAXN],vis[MAXN]={};
    inline int getfather(int x){
        return x==f[x]?x:f[x]=getfather(f[x]);
    }
    int main(){
        //freopen("All.in","r",stdin);
        //freopen("a.out","w",stdout);
        int n=read();int m=read();
        for(int i=1;i<=n;i++){
            f[i]=i;
        }
        for(int i=1;i<=m;i++){
            int xx=read();int yy=read();
            int fx=getfather(xx);int fy=getfather(yy);
            if(fx==fy) vis[fy]=1;
            else vis[fy]|=vis[fx],vis[fx]|=vis[fy],f[fx]=fy;
        } 
        for(int i=1;i<=n;i++){
            if(!vis[getfather(i)]){
                cout<<"NIE"<<endl;
                return 0;
            }
        }
        cout<<"TAK"<<endl;
        return 0;
    }
    

    对拍代码

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    int main(){
        freopen("All.in","w",stdout);
        srand(time(int(NULL)));
        int n=rand()%10007+1;
        int m=rand()%100007+1+n;
        cout<<n<<' '<<m<<endl;
        for(int i=1;i<=m;i++){
            printf("%d %d
    ",rand()%n+1,rand()%n+1);
        }
        return 0;
    }
    
  • 相关阅读:
    现代软件工程 第一周博客作业
    最后一周总结
    阅读后感
    软件工程作业个人项目——csdn app分析
    第二次结对编程
    软件工程作业二
    软件工程作业一
    ASE 课程最后小结
    阅读后感
    Judy Beta 第五天
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/7976500.html
Copyright © 2011-2022 走看看