• 网络流


    先贴个ISAP的算法模板 从源点s到汇点t  结点共有n个

    算法部分基本都是这模板 主要看思路和建图

      1 #include<iostream>
      2 #include<vector>
      3 #include<string.h>
      4 #include<queue>
      5 #include<cstdio>
      6 using namespace std;
      7 struct E{int from;int to;int c;int f;};
      8 vector <int> g[220];
      9 vector<E> edge;
     10 int d[220],vis[220],cur[220],num[220],p[220];
     11 #define INF 10000000
     12 
     13 void add(int from,int to,int c)
     14 {
     15     E temp1,temp2;
     16     temp1.from =from; temp1.to=to; temp1.c=c;temp1.f=0;
     17     temp2.from =to; temp2.to=from; temp2.c=0;temp2.f=0;
     18     edge.push_back (temp1);
     19     edge.push_back (temp2);
     20     int m=edge.size ();
     21     g[from].push_back (m-2);
     22     g[to].push_back (m-1);
     23 }
     24 
     25 void bfs(int s,int t)
     26 {
     27     int i;
     28     queue<int > q;
     29     q.push (t);
     30     d[t]=0;
     31     memset(vis,0,sizeof(vis));
     32     vis[t]=1;
     33     while(!q.empty ())
     34     {
     35         int t=q.front ();q.pop ();
     36         for(i=0;i<g[t].size ();i++)
     37         {
     38            E e;e=edge[g[t][i]];
     39            if(!vis[e.to])
     40            {
     41                q.push (e.to);
     42                vis[e.to]=1;
     43                d[e.to]=d[t]+1;
     44            }
     45         }
     46     }
     47 }
     48 
     49 int zg(int s,int t)
     50 {
     51     int x=t,a=INF;
     52     while(x!=s)
     53     {
     54         //printf("x   %d
    ",x);
     55         E e=edge[p[x]];
     56         if(a>e.c-e.f)
     57             a=e.c-e.f;
     58         x=e.from;
     59     }
     60     x=t;
     61     while(x!=s)
     62     {
     63         edge[p[x]].f+=a;
     64         edge[p[x]^1].f-=a;
     65         x=edge[p[x]].from ;
     66     }
     67     return a;
     68 }
     69 
     70 int maxflow(int s,int t,int n)
     71 {
     72     int flow=0,i;
     73     bfs(s,t);
     74     memset(num,0,sizeof(num));
     75     memset(cur,0,sizeof(cur));
     76     for(i=0;i<=t;i++)
     77         num[d[i]]++;
     78     int x=s;
     79     while(d[s]<=n)
     80     {
     81         if(x==t)
     82         {
     83             flow+=zg(s,t);
     84             x=s;
     85             //printf("flow  %d
    ",flow);
     86         }
     87         int ok=0;
     88         for(i=cur[x];i<g[x].size ();i++)
     89         {
     90             E e;
     91             e=edge[g[x][i]];
     92             if(e.c>e.f&&d[x]==d[e.to]+1)
     93             {
     94                 ok=1;
     95 
     96                 p[e.to]=g[x][i];
     97 
     98                 cur[x]=i;
     99                 x=e.to;//!@#$%^&
    100                 break;
    101             }
    102         }
    103         if(ok==0)
    104         {
    105             int m=n;
    106             for(i=0;i<g[x].size ();i++)
    107             {
    108                 E e;
    109                 e=edge[g[x][i]];
    110                 if(e.c>e.f&&m>d[e.to])
    111                     m=d[e.to];
    112             }
    113             if(--num[d[x]]==0)  break;
    114             num[d[x]=m+1]++;
    115             cur[x]=0;////!@#$%^^&
    116             if(x!=s)
    117                 x=edge[p[x]].from ;
    118 
    119         }
    120     }
    121     return flow;
    122 }

    poj  1149 pigs

    http://poj.org/problem?id=1149  

    题意: 有m个猪栏和 n个来买猪的人 给出每个猪栏里的数量 和 每个来的人能开的猪栏标号 和他要买的猪的数量  他打开这些门后可以将 里面的猪重新分配   求 最多可以卖多少猪

    思路:网络流 将来的人 和 开某一个猪栏的门则  这个人和源点连一条边 容量为 这个猪栏里 的猪的数量 而若是那个猪栏已经被人打开过也就是 可能之前就被重新分配了 则这个人 和前面 的这个人连一条 无限大的边  最后这n个人各和 汇点连一条边 容量为 他要买的猪的数量

      1 #include<iostream>
      2 #include<vector>
      3 #include<string.h>
      4 #include<queue>
      5 using namespace std;
      6 struct E{int from;int to;int c;int f;};
      7 vector <int> g[202];
      8 vector<E> edge;
      9 int d[102],vis[102],cur[102],num[102],p[102],w[1102],need[120],n;
     10 #define INF 10000000
     11 
     12 void add(int from,int to,int c)
     13 {
     14     E temp1,temp2;
     15     temp1.from =from; temp1.to=to; temp1.c=c;temp1.f=0;
     16     temp2.from =to; temp2.to=from; temp2.c=0;temp2.f=0;
     17     edge.push_back (temp1);
     18     edge.push_back (temp2);
     19     int m=edge.size ();
     20     g[from].push_back (m-2);
     21     g[to].push_back (m-1);
     22 }
     23 
     24 void bfs(int s,int t)
     25 {
     26     int i;
     27     queue<int > q;
     28     q.push (t);
     29     d[t]=0;
     30     memset(vis,0,sizeof(vis));
     31     vis[t]=1;
     32     while(!q.empty ())
     33     {
     34         int t=q.front ();q.pop ();
     35         for(i=0;i<g[t].size ();i++)
     36         {
     37            E e;e=edge[g[t][i]];
     38            if(!vis[e.to])
     39            {
     40                q.push (e.to);
     41                vis[e.to]=1;
     42                d[e.to]=d[t]+1;
     43            }
     44         }
     45     }
     46 }
     47 
     48 int zg(int s,int t)
     49 {
     50     int x=t,a=INF;
     51     while(x!=s)
     52     {
     53         //printf("x   %d
    ",x);        
     54         E e=edge[p[x]];
     55         if(a>e.c-e.f)
     56             a=e.c-e.f;
     57         x=e.from;
     58     }
     59     x=t;
     60     while(x!=s)
     61     {
     62         edge[p[x]].f+=a;
     63         edge[p[x]^1].f-=a;
     64         x=edge[p[x]].from ;
     65     }
     66     return a;
     67 }
     68 
     69 int maxflow(int s,int t,int n)
     70 {
     71     int flow=0,i;
     72     bfs(s,t);
     73     memset(num,0,sizeof(num));
     74     memset(cur,0,sizeof(cur));
     75     for(i=0;i<=t;i++)
     76         num[d[i]]++;
     77     int x=s;
     78     while(d[s]<n)
     79     {
     80         if(x==t)
     81         {
     82             flow+=zg(s,t);
     83             x=s;
     84             //printf("flow  %d
    ",flow);
     85         }
     86         int ok=0;
     87         for(i=cur[x];i<g[x].size ();i++)
     88         {
     89             E e;
     90             e=edge[g[x][i]];
     91             if(e.c>e.f&&d[x]==d[e.to]+1)
     92             {
     93                 ok=1;
     94                 
     95                 p[e.to]=g[x][i];
     96             
     97                 cur[x]=i;
     98                 x=e.to;//!@#$%^&
     99                 break;
    100             }
    101         }
    102         if(ok==0)
    103         {
    104             int m=n;
    105             for(i=0;i<g[x].size ();i++)
    106             {
    107                 E e;
    108                 e=edge[g[x][i]];
    109                 if(e.c>e.f&&m>d[e.to])
    110                     m=d[e.to];
    111             }
    112             if(--num[d[x]]==0)  break;
    113             num[d[x]=m+1]++;
    114             cur[x]=0;////!@#$%^^&
    115             if(x!=s)
    116                 x=edge[p[x]].from ;
    117             
    118         }
    119     }
    120     return flow;
    121 }
    122 
    123 
    124 int main()
    125 {
    126     int i,j,m,t,pp[1102],u,num;
    127     while(~scanf("%d%d",&m,&n))
    128     {
    129         memset(pp,-1,sizeof(pp));
    130         for(i=1;i<=m;i++)    
    131         {
    132             scanf("%d",&w[i]);
    133         //    add(0,i,w[i]);
    134         }
    135             
    136         
    137         for(i=1;i<=n;i++)
    138         {
    139             scanf("%d",&num);
    140             while(num--)
    141             {
    142                 scanf("%d",&u);
    143                 if(pp[u]==-1)
    144                 {
    145                     add(0,i,w[u]);
    146                     pp[u]=i;
    147                 }
    148                 else
    149                 {
    150                     add(pp[u],i,INF);
    151                     pp[u]=i;
    152                 }
    153             
    154             }
    155             scanf("%d",&need[i]);
    156         }
    157         for(i=1;i<=n;i++)
    158             add(i,n+1,need[i]);
    159         int ans=maxflow(0,n+1,n+1);
    160         printf("%d
    ",ans);
    161         edge.clear ();
    162         for(i=0;i<=n+1;i++)
    163             g[i].clear ();
    164     }
    165     return 0;
    166 }
    View Code

    poj 2455 Secret Milking Machine

    http://poj.org/problem?id=2455

    题意:FJ有N块地,这些地之间有P条双向路,每条路的都有固定的长度l。现在要你找出从第1块地到第n块地的T条不同路径,每条路径上的路不能与先前的路径重复,问这些路径中的最长路的最小是多少。(注意找的是 路径    是两两之间的 路径)

    思路:路径不能重复 想到网络流 找最大的最小 想到二分,

            二分这个值为mid 要是   i 到 j 有路 且 他们的长度<=mid  就把 i到j连一条边容量为1  s为1   t为 n   求最大流  最大流就是他们不同的路径        的数量

    注意:  因为是无向图 所以建边要建两条

               add(ee[i].x,ee[i].y,1);
               add(ee[i].y,ee[i].x,1);

      1 #include<iostream>
      2 #include<stdio.h>
      3 #include<string.h>
      4 #include<vector>
      5 #include<queue>
      6 using namespace std;
      7 
      8 #define INF 10000000
      9 struct node{int x;int y;int w;}ee[40002];
     10 struct E{int from;int to;int f;int c;};
     11 vector<E> edge;
     12 vector<int > g[202];
     13 int num[202],d[202],vis[202],cur[202],p[202];
     14 
     15 void add(int from,int to,int c)
     16 {
     17     E temp1,temp2;
     18     temp1.from =from; temp1.to=to; temp1.c=c;temp1.f=0;
     19     temp2.from =to; temp2.to=from; temp2.c=0;temp2.f=0;
     20     edge.push_back (temp1);
     21     edge.push_back (temp2);
     22     int m=edge.size ();
     23     g[from].push_back (m-2);
     24     g[to].push_back (m-1);
     25 }
     26 
     27 void bfs(int s,int t)
     28 {
     29     int i;
     30     queue<int > q;
     31     q.push (t);
     32     d[t]=0;
     33     memset(vis,0,sizeof(vis));
     34     vis[t]=1;
     35     while(!q.empty ())
     36     {
     37         int t=q.front ();q.pop ();
     38         for(i=0;i<g[t].size ();i++)
     39         {
     40            E e;e=edge[g[t][i]];
     41            if(!vis[e.to])
     42            {
     43                q.push (e.to);
     44 
     45 
     46 int zg(int s,int t)
     47 {
     48     int x=t,a=INF;
     49     while(x!=s)
     50     {
     51         E e=edge[p[x]];
     52         if(a>e.c-e.f)
     53             a=e.c-e.f;
     54         x=e.from;
     55     }
     56     x=t;
     57     while(x!=s)
     58     {
     59         edge[p[x]].f+=a;
     60         edge[p[x]^1].f-=a;
     61         x=edge[p[x]].from ;
     62     }
     63     return a;
     64 }
     65 
     66 int maxflow(int s,int t,int n)
     67 {
     68     int flow=0,i;
     69     bfs(s,t);
     70     memset(num,0,sizeof(num));
     71     memset(cur,0,sizeof(cur));
     72     for(i=0;i<=t;i++)
     73         num[d[i]]++;
     74     int x=s;
     75     while(d[s]<n)
     76     {
     77         if(x==t)
     78         {
     79             flow+=zg(s,t);
     80             x=s;            
     81         }
     82         int ok=0;
     83         for(i=cur[x];i<g[x].size ();i++)
     84         {
     85             E e;
     86             e=edge[g[x][i]];
     87             if(e.c>e.f&&d[x]==d[e.to]+1)
     88             {
     89                 ok=1;
     90 
     91                 p[e.to]=g[x][i];
     92 
     93                 cur[x]=i;
     94                 x=e.to;
     95                 break;
     96             }
     97         }
     98         if(ok==0)
     99         {
    100             int m=n;
    101             for(i=0;i<g[x].size ();i++)
    102             {
    103                 E e;
    104                 e=edge[g[x][i]];
    105                 if(e.c>e.f&&m>d[e.to])
    106                     m=d[e.to];
    107             }
    108             if(--num[d[x]]==0)  break;
    109             num[d[x]=m+1]++;
    110             cur[x]=0;
    111             if(x!=s)    
    112                 x=edge[p[x]].from ;
    113 
    114         }
    115     }
    116     return flow;
    117 }
    118 
    119 int main()
    120 {
    121     int i,j,m,n,t,p;
    122     while(~scanf("%d%d%d",&n,&m,&p))
    123     {
    124 
    125 
    126         int minn=INF,maxx=0;
    127         for(i=0;i<m;i++)
    128         {
    129             scanf("%d%d%d",&ee[i].x,&ee[i].y,&ee[i].w);
    130             if(ee[i].w>maxx)
    131                 maxx=ee[i].w;
    132             if(ee[i].w<minn)
    133                 minn=ee[i].w;
    134         }
    135 
    136 
    137         int low=minn,high=maxx;
    138         int best;
    139         while(low<=high)
    140         {
    141             int mid=(high+low)/2;
    142 
    143                 edge.clear();
    144         for(i=0;i<=n;i++)
    145             g[i].clear();
    146 
    147             for(i=0;i<m;i++)
    148                 if(ee[i].w<=mid)
    149                 {
    150                     add(ee[i].x,ee[i].y,1);
    151                     add(ee[i].y,ee[i].x,1);
    152 
    153             }
    154 
    155             int ans=maxflow(1,n,n);
    156 
    157             if(ans>=p)
    158             {
    159                 best=mid;
    160                 high=mid-1;
    161             }
    162             else low=mid+1;
    163         }
    164         printf("%d
    ",best);
    165 
    166 
    167     }
    168     return 0;
    169 }
    View Code
  • 相关阅读:
    virtio前端驱动详解
    virtIO前后端notify机制详解
    virtio后端驱动详解
    centos7手动编译安装Libvirt常见问题
    手动编译安装Libvirt之后利用systemctl管理libvirtd服务
    android学习点滴一:android环境的搭建
    phpcms换域名细节
    apache配置中的小细节
    娱乐一下-加班的不归路
    qt5.3+vs2013乱码
  • 原文地址:https://www.cnblogs.com/assult/p/3306288.html
Copyright © 2020-2023  润新知