zoukankan      html  css  js  c++  java
  • BZOJ1116: [POI2008]CLO

    1116: [POI2008]CLO

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 565  Solved: 303
    [Submit][Status]

    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

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

     题解:

    又被并查集虐哭了。。。

    hzwer:

    首先我们可以推出一个性质,当且仅当某一个连通块中没有环存在输出NIE
    于是我们可以用并查集把这题水过。。
    给每个连通块的根一个标记
    合并俩个连通块时只要任意一个连通块带有标记新的连通块就带有标记
    如果一条边的俩个点已经在同一个连通块内了,直接将根打上标记即可
    然后最后扫一遍,如果哪个连通块没有标记的话输出NIE
    否则最后输出TAK
    -----------------------------------------------------------------------------------------------------------
    代码:
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 100000+100
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 using namespace std;
    22 inline int read()
    23 {
    24     int x=0,f=1;char ch=getchar();
    25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    27     return x*f;
    28 }
    29 int n,m,fa[maxn];
    30 bool mark[maxn];
    31 inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);};
    32 int main()
    33 {
    34     freopen("input.txt","r",stdin);
    35     freopen("output.txt","w",stdout);
    36     n=read();m=read();
    37     for1(i,n)fa[i]=i;
    38     for1(i,m)
    39      {
    40          int x=find(read()),y=find(read());
    41          if(x==y)mark[x]=1;else fa[x]=y,mark[y]=mark[x]||mark[y];
    42      }
    43     for1(i,n)if(!mark[find(i)]){cout<<"NIE"<<endl;return 0;}
    44     cout<<"TAK"<<endl;
    45     return 0;
    46 }
    View Code

    网络流看起来是可行的,但T成翔啊。。。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 1000000
    14 #define maxm 1000000
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 using namespace std;
    22 inline int read()
    23 {
    24     int x=0,f=1;char ch=getchar();
    25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    27     return x*f;
    28 }
    29 int n,m,s,t,maxflow,tot=1,head[maxn],q[maxm],d[maxn],h[maxn],cur[maxn];
    30 bool v[maxn];
    31 struct edge{int from,next,go,v;}e[2*maxm];
    32 void ins(int x,int y,int z){e[++tot].go=y;e[tot].v=z;e[tot].next=head[x];head[x]=tot;}
    33 void insert(int x,int y,int z){ins(x,y,z);ins(y,x,0);}
    34 bool bfs()
    35 {
    36     for(int i=s;i<=t;i++)h[i]=-1;
    37     int l=0,r=1;q[1]=s;h[s]=0;
    38     while(l<r) 
    39     {
    40         int x=q[++l];
    41         for(int i=head[x];i;i=e[i].next)
    42          if(e[i].v&&h[e[i].go]==-1)
    43          {
    44              h[e[i].go]=h[x]+1;q[++r]=e[i].go;
    45          }
    46     }
    47     return h[t]!=-1;
    48 }
    49 int dfs(int x,int f)
    50 {
    51     if(x==t) return f;
    52     int tmp,used=0,i;
    53     for(int i=head[x];i;i=e[i].next)
    54      if(e[i].v&&h[e[i].go]==h[x]+1) 
    55     {
    56         tmp=dfs(e[i].go,min(e[i].v,f-used));
    57         e[i].v-=tmp;if(e[i].v)cur[x]=i; 
    58         e[i^1].v+=tmp;used+=tmp;
    59         if(used==f)return f;         
    60     }
    61     if(!used) h[x]=-1;
    62     return used; 
    63 }
    64 void dinic()
    65 {
    66     maxflow=0;
    67     while(bfs())
    68     {
    69         for (int i=s;i<=t;i++)cur[i]=head[i];maxflow+=dfs(s,inf); 
    70     } 
    71 }
    72 int main()
    73 {
    74     freopen("input.txt","r",stdin);
    75     freopen("output.txt","w",stdout);
    76     n=read();m=read();s=0;t=m+n+n+1;
    77     for1(i,m)
    78      {
    79          int x=read(),y=read();
    80          insert(s,i,1);
    81          insert(i,m+x,1);insert(i,m+y,1);
    82          insert(m+x,m+n+y,1);insert(m+y,m+n+x,1);
    83      }
    84     for1(i,n)insert(m+n+i,t,1);
    85     dinic();
    86     if(maxflow==n)cout<<"TAK"<<endl;else cout<<"NIE"<<endl;
    87     return 0;
    88 }
    View Code
  • 相关阅读:
    HDU 4539郑厂长系列故事――排兵布阵(状压DP)
    HDU 2196Computer(树形DP)
    HDU 4284Travel(状压DP)
    HDU 1520Anniversary party(树型DP)
    HDU 3920Clear All of Them I(状压DP)
    HDU 3853LOOPS(简单概率DP)
    UVA 11983 Weird Advertisement(线段树求矩形并的面积)
    POJ 2886Who Gets the Most Candies?(线段树)
    POJ 2828Buy Tickets
    HDU 1394Minimum Inversion Number(线段树)
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3966507.html
Copyright © 2011-2022 走看看