• poj 1149


      

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 #define _clr(x, y) memset(x, y, sizeof(x))
      5 #define Min(x, y) (x < y ? x : y)
      6 #define INF 0x3f3f3f3f
      7 #define N 150
      8 #define M 1005
      9 using namespace std;
     10 
     11 int resi[N][N], h[N], ef[N];
     12 int dist[N], pre[N];
     13 int Maxf, S, T;
     14 bool used[N];
     15 queue<int> Q;
     16 
     17 //  一般预流推进算法 --47ms
     18 void Push(int x)
     19 {
     20     for(int i=0; i<=T; i++)
     21     {
     22         int tmp = Min(ef[x], resi[x][i]);
     23         if(tmp>0 && (x==S || h[x]==h[i]+1))
     24         {
     25             resi[x][i] -= tmp, resi[i][x] += tmp;
     26             ef[x] -= tmp, ef[i] += tmp;
     27             if(i==T) Maxf += tmp;
     28             if(i!=S && i!=T) Q.push(i);
     29         }
     30     }
     31 }
     32 
     33 void Push_Relabel(int n)
     34 {
     35     Maxf = 0;
     36     _clr(ef, 0);
     37     _clr(h, 0);
     38     h[S] = n, ef[S]=INF, ef[T]=-INF;
     39     Q.push(S);
     40     while(!Q.empty())
     41     {
     42         int x = Q.front();
     43         Q.pop();
     44         Push(x);
     45         if(x!=S && x!=T && ef[x]>0)
     46         {
     47             h[x]++;
     48             Q.push(x);
     49         }
     50     }
     51     printf("%d
    ",Maxf);
     52 }
     53 
     54 void Init(int m, int n)
     55 {   
     56     int pig[M], last[M];
     57     int num, k;
     58     S=0, T=n+1;
     59     _clr(last, 0);
     60     _clr(resi, 0);
     61     for(int i=1; i<=m; i++)
     62        scanf("%d", pig+i);
     63     for(int i=1; i<=n; i++)
     64     {
     65         scanf("%d", &num);
     66         for(int j=0; j<num; j++)
     67         {
     68             scanf("%d", &k);
     69             if(last[k]==0)
     70                 resi[S][i] += pig[k];
     71             else
     72                 resi[last[k]][i] = INF;
     73             last[k] = i;
     74         }
     75         scanf("%d", resi[i]+T);
     76     }
     77 }
     78 
     79 // 连续最短曾广路算法  --17ms
     80 bool bfs_dinic()
     81 {
     82     _clr(dist, -1);
     83     dist[S] = 0;
     84     Q.push(S);
     85     while(!Q.empty())
     86     {
     87         int u = Q.front();
     88         Q.pop();
     89         for(int i=0; i<=T; i++)
     90         {
     91             if(dist[i]<0 && resi[u][i])
     92             {
     93                 dist[i] = dist[u]+1;
     94                 Q.push(i);
     95             }
     96         }
     97     }
     98     return dist[T]>0 ? 1 : 0;
     99 }
    100 
    101 int dfs(int x, int f)
    102 {
    103     int a=0;
    104     if(x==T) return f;
    105     for(int i=0; i<=T; i++)
    106     {
    107         if(resi[x][i] && dist[i]==dist[x]+1 && (a=dfs(i, Min(f, resi[x][i]))))
    108         {
    109             resi[x][i] -= a, resi[i][x] += a;
    110             return a;
    111         }
    112     }
    113     return 0;
    114 }
    115 
    116 void Dinic()
    117 {
    118     int ans=0, a;
    119     while(bfs_dinic())
    120         while(a=dfs(0, INF)) ans+= a;
    121     printf("%d
    ", ans);
    122 }
    123 
    124 //  EK算法   --0ms
    125 bool bfs()
    126 {
    127     _clr(used, 0);
    128     _clr(pre, -1);
    129     int Sta[N], top=0;
    130     used[S] = true;
    131     Sta[top++] = S;
    132     while(top)
    133     {
    134         int u = Sta[--top];
    135         for(int i=0; i<=T; i++)
    136         {
    137             if(resi[u][i] && !used[i])
    138             {
    139                 used[i] = true;
    140                 pre[i] = u;
    141                 if(i==T) return true;
    142                 Sta[top++] = i;
    143             }
    144         }
    145     }
    146     return false;
    147 }
    148 void EK()
    149 {
    150     int maxf=0, d;
    151     while(bfs())
    152     {
    153         d = INF;
    154         for(int i=T; i!=S; i=pre[i])
    155             d = Min(d, resi[pre[i]][i]);
    156         for(int i=T; i!=S; i=pre[i])
    157         {
    158             resi[pre[i]][i] -= d;
    159             resi[i][pre[i]] += d;
    160         }
    161         maxf += d;
    162     }
    163     printf("%d
    ", maxf);
    164 }
    165 int main()
    166 {
    167     int n, m;
    168     while(~scanf("%d%d", &m, &n))
    169     {
    170         while(!Q.empty()) Q.pop();
    171         Init(m, n);
    172         EK();
    173         //Push_Relabel(n);
    174         //Dinic();
    175     }
    176     return 0;
    177 }
  • 相关阅读:
    极简风格的LOGO,收集一波!
    如何利用AI软件中的混合器工具制作文字
    国内有哪些非常有设计感的 App?
    如何用PS制作花型背景图
    怎样去调整摄影作品的背景颜色
    如何用PS把数码拍摄的荷花照片制作成中国风的效果
    PS 抠人像如何抠得干净?
    如何用 Ps 制作毛玻璃穿透效果?
    化装品经过这样PS包装,身价立马翻10倍
    有哪些漂亮的中国风 LOGO 设计?
  • 原文地址:https://www.cnblogs.com/khan724/p/4311489.html
Copyright © 2020-2023  润新知