• hdu 3081


    二分答案,网络流是否满流判断合法性。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 #include <vector>
      5 #define maxn 210
      6 #define oo 0x3f3f3f3f
      7 using namespace std;
      8 
      9 struct Edge {
     10     int u, v, f;
     11     Edge( int u, int v, int f ):u(u),v(v),f(f){}
     12 };
     13 struct Dinic {
     14     int n, src, dst;
     15     vector<Edge> edge;
     16     vector<int> g[maxn];
     17     int dep[maxn], cur[maxn];
     18 
     19     void init( int n, int src, int dst  ) {
     20         this->n = n;
     21         this->src = src;
     22         this->dst = dst;
     23         for( int u=1; u<=n; u++ )
     24             g[u].clear();
     25         edge.clear();
     26     }
     27     void add_edge( int u, int v, int f ) {
     28         g[u].push_back( edge.size() );
     29         edge.push_back( Edge(u,v,f) );
     30         g[v].push_back( edge.size() );
     31         edge.push_back( Edge(v,u,0) );
     32     }
     33     bool bfs() {
     34         queue<int> qu;
     35         memset( dep, 0, sizeof(dep) );
     36         qu.push( src );
     37         dep[src] = 1;
     38         while( !qu.empty() ) {
     39             int u=qu.front();
     40             qu.pop();
     41             for( int &t=cur[u]; t<g[u].size(); t++ ) {
     42                 Edge &e = edge[g[u][t]];
     43                 if( e.f && !dep[e.v] ) {
     44                     dep[e.v] = dep[e.u]+1;
     45                     qu.push( e.v );
     46                 }
     47             }
     48         }
     49         return dep[dst];
     50     }
     51     int dfs( int u, int a ) {
     52         if( u==dst || a==0 ) return a;
     53         int remain=a, past=0, na;
     54         for( int &t=cur[u]; t<g[u].size(); t++ ) {
     55             Edge &e = edge[g[u][t]];
     56             Edge &ve = edge[g[u][t]^1];
     57             if( dep[e.v]==dep[e.u]+1 && (na=dfs(e.v,min(remain,e.f))) ) {
     58                 remain -= na;
     59                 past += na;
     60                 e.f -= na;
     61                 ve.f += na;
     62                 if( remain==0 ) break;
     63             }
     64         }
     65         return past;
     66     }
     67     int maxflow() {
     68         int flow = 0;
     69         while( bfs() ) {
     70             memset( cur, 0, sizeof(cur) );
     71             flow += dfs(src,oo);
     72         }
     73         return flow;
     74     }
     75 };
     76 
     77 int fa[maxn];
     78 
     79 void init( int n ) {
     80     for( int i=1; i<=n; i++ )
     81         fa[i] = i;
     82 }
     83 int find( int a ) {
     84     return a==fa[a] ? a : fa[a]=find(fa[a]);
     85 }
     86 void unon( int a, int b ) {
     87     a = find(a);
     88     b = find(b);
     89     fa[a] = b;
     90 }
     91 
     92 int n, m, f;
     93 bool cnnt[110][110];
     94 int cnt[110];
     95 vector<int> stk;
     96 Dinic D;
     97 
     98 bool ok( int mid ) {
     99     D.init( n+n+2, n+n+1, n+n+2 );
    100     for( int u=1; u<=n; u++ ) {
    101         if( fa[u]!=u ) continue;
    102         D.add_edge( D.src, u, mid*cnt[u] );
    103         for( int v=1; v<=n; v++ ) {
    104             if( !cnnt[u][v] ) continue;
    105             D.add_edge( u, v+n, cnt[u] );
    106         }
    107     }
    108     for( int v=1; v<=n; v++ ) 
    109         D.add_edge( v+n, D.dst, mid );
    110     return D.maxflow()==mid*n;
    111 }
    112 int main() {
    113     int T;
    114     scanf( "%d", &T );
    115     while( T-- ) {
    116         scanf( "%d%d%d", &n, &m, &f );
    117         memset( cnnt, 0, sizeof(cnnt) );
    118         for( int i=1,u,v; i<=m; i++ ) {
    119             scanf( "%d%d", &u, &v );
    120             cnnt[u][v] = 1;
    121         }
    122         init(n);
    123         for( int i=1,u,v; i<=f; i++ ) {
    124             scanf( "%d%d", &u, &v );
    125             unon(u,v);
    126         }
    127         memset( cnt, 0, sizeof(cnt) );
    128         for( int i=1; i<=n; i++ ) {
    129             int r = find(i);
    130             cnt[r]++;
    131             for( int j=1; j<=n; j++ )
    132                 cnnt[r][j] |= cnnt[i][j];
    133         }
    134         stk.clear();
    135         for( int i=1; i<=n; i++ )
    136             if( fa[i]==i ) stk.push_back(i);
    137         int lf=0, rg=n;
    138         while( lf<rg ) {
    139             int mid = (lf+rg+1)>>1;
    140             if( ok(mid) ) lf=mid;
    141             else rg=mid-1;
    142         }
    143         printf( "%d
    ", lf );
    144     }
    145 }
    View Code
  • 相关阅读:
    C语言 递归 汉诺塔问题 最大公约数问题
    程序的健壮性及代码风格
    C程序练习
    专题——条件控制循环 猜数游戏 随机种子
    C语言 分支与循环 递推思想 穷举 流程的转移控制
    C指针 指针和数组 二维数组的指针 指针应用
    C语言实现的排序
    数组查找算法的C语言 实现-----线性查找和二分查找
    图片转成base64 跨域等安全限制及解决方案
    移动开发那些坑之——safari mobile click事件的冒泡bug
  • 原文地址:https://www.cnblogs.com/idy002/p/4321978.html
Copyright © 2020-2023  润新知