• SGU 176 (有源汇最小流)


    转载:http://blog.csdn.net/dan__ge/article/details/51207951

    题意:n个节点,m条路径,接下来m行a,b,c,d,如果d等于1,则a到b的流量必须为c,如果d等于0,流量可以为0到c,问如果有可行流,最小流量和每条边的流量

    思路:最小流的解法与其他的不同,我们先将其变成无源汇的做法,建立超级源点和汇点,然后跑最大流,之后在加上汇点到源点的inf边,再跑最大流,如果满流则说明有解,不然无解,而最小的流量就是汇点到源点跑得流量

     1 #include <queue>
     2 #include <vector>
     3 #include <stdio.h>
     4 #include <string.h>
     5 #include <stdlib.h>
     6 #include <iostream>
     7 #include <algorithm>
     8 #include <functional>
     9 using namespace std;
    10 typedef long long ll;
    11 const int inf=0x3f3f3f3f;
    12 const int maxn=150;
    13 struct edge{
    14     int to,cap,rev;
    15     edge(int a,int b,int c){to=a;cap=b;rev=c;}
    16 };
    17 vector<edge>G[maxn];
    18 int level[maxn],iter[maxn];
    19 void add_edge(int from,int to,int cap){
    20     G[from].push_back(edge(to,cap,G[to].size()));
    21     G[to].push_back(edge(from,0,G[from].size()-1));
    22 }
    23 void bfs(int s){
    24     memset(level,-1,sizeof(level));
    25     queue<int>que;level[s]=0;
    26     que.push(s);
    27     while(!que.empty()){
    28         int v=que.front();que.pop();
    29         for(unsigned int i=0;i<G[v].size();i++){
    30             edge &e=G[v][i];
    31             if(e.cap>0&&level[e.to]<0){
    32                 level[e.to]=level[v]+1;
    33                 que.push(e.to);
    34             }
    35         }
    36     }
    37 }
    38 int dfs(int v,int t,int f){
    39     if(v==t) return f;
    40     for(int &i=iter[v];i<G[v].size();i++){
    41         edge &e=G[v][i];
    42         if(e.cap>0&&level[v]<level[e.to]){
    43             int d=dfs(e.to,t,min(f,e.cap));
    44             if(d>0){
    45                 e.cap-=d;
    46                 G[e.to][e.rev].cap+=d;
    47                 return d;
    48             }
    49         }
    50     }
    51     return 0;
    52 }
    53 int max_flow(int s,int t){
    54     int flow=0;
    55     while(1){
    56         bfs(s);
    57         if(level[t]<0) return flow;
    58         memset(iter,0,sizeof(iter));
    59         int f;
    60         while((f=dfs(s,t,inf))>0) flow+=f;
    61     }
    62 }
    63 int L[10010],R[10010],num[10010][2];
    64 int main(){
    65     int n,m,a,b,d,c;
    66     while(scanf("%d%d",&n,&m)!=-1){
    67         for(int i=0;i<maxn;i++) G[i].clear();
    68         int sum=0,S=n+1,T=n+2;
    69         for(int i=0;i<m;i++){
    70             scanf("%d%d%d%d",&a,&b,&c,&d);
    71             if(d==1){
    72                 L[i]=c;R[i]=c;
    73             }else{
    74                 L[i]=0,R[i]=c;
    75             }
    76             add_edge(a,b,R[i]-L[i]);
    77             sum+=L[i];
    78             num[i][0]=a;num[i][1]=G[a].size()-1;
    79             add_edge(S,b,L[i]);add_edge(a,T,L[i]);
    80         }
    81         int ans=max_flow(S,T);
    82         add_edge(n,1,inf);
    83         int kk=G[1].size()-1;
    84         int ans1=max_flow(S,T);
    85         if(ans+ans1!=sum) printf("Impossible
    ");
    86         else{
    87             printf("%d
    ",G[1][kk].cap);
    88             for(int i=0;i<m-1;i++){
    89                 printf("%d ",R[i]-G[num[i][0]][num[i][1]].cap);
    90             }
    91             printf("%d
    ",R[m-1]-G[num[m-1][0]][num[m-1][1]].cap);
    92         }
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    4.比赛F
    4.M
    4.H
    4.J
    4.G
    4.D
    4.C
    UVA 215 Spreadsheet Calculator (模拟)
    POJ 3469 Dual Core CPU(最小割模型的建立)
    POJ 3281 Dining(网络流最大匹配)
  • 原文地址:https://www.cnblogs.com/agenthtb/p/7689555.html
Copyright © 2020-2023  润新知