poj 3228(二分+最大流)

题目链接:http://poj.org/problem?id=3228

思路:增设一个超级源点和一个超级汇点,源点与每一个gold相连,容量为gold数量,汇点与仓库相连,容量为仓库的容量,然后就是二分最小的最大相邻距离,跑最大流验证即可。最大流用的是别人的Dinic模版。

  1 #include<iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<algorithm>

  5 #include<queue>

  6 using namespace std;

  7 #define MAXN 222

  8 #define inf 1<<30

  9 

 10 int vs,vt;

 11 int dep[MAXN];

 12 int map[MAXN][MAXN];

 13 

 14 int gold[MAXN],store[MAXN];

 15 int dist[MAXN][MAXN];

 16 void Build_Map(int limit,int n)

 17 {

 18     memset(map,0,sizeof(map));

 19     for(int i=1;i<=n;i++)

 20         for(int j=1;j<=n;j++)

 21             if(dist[i][j]<=limit)map[i][j]=inf;

 22     for(int i=1;i<=n;i++){

 23         map[vs][i]=gold[i];

 24         map[i][vt]=store[i];

 25     }

 26 }

 27 

 28 int BFS(){

 29     queue<int> q;

 30     while(!q.empty())

 31         q.pop();

 32     memset(dep,-1,sizeof(dep));

 33     dep[vs]=0;

 34     q.push(vs);

 35     while(!q.empty()){

 36         int u=q.front();

 37         q.pop();

 38         for(int v=vs;v<=vt;v++)

 39             if(map[u][v]>0 && dep[v]==-1){

 40                 dep[v]=dep[u]+1;

 41                 q.push(v);

 42             }

 43     }

 44     return dep[vt]!=-1;

 45 }

 46 

 47 int DFS(int u,int minx){

 48     if(u==vt)

 49         return minx;

 50     int tmp;

 51     for(int v=vs;v<=vt;v++)

 52         if(map[u][v]>0 && dep[v]==dep[u]+1 && (tmp=DFS(v,min(minx,map[u][v])))){

 53             map[u][v]-=tmp;

 54             map[v][u]+=tmp;

 55             return tmp;

 56         }

 57     dep[u]=-1;

 58     return 0;

 59 }

 60 

 61 int Dinic(){

 62     int ans=0,tmp;

 63     while(BFS()){

 64         while(1){

 65             tmp=DFS(vs,inf);

 66             if(tmp==0)

 67                 break;

 68             ans+=tmp;

 69         }

 70     }

 71     return ans;

 72 }

 73 

 74 int main()

 75 {

 76     int total,n,m,a,b,c;

 77     while(~scanf("%d",&n)){

 78         if(n==0)break;

 79         total=0,vs=0,vt=n+1;

 80         for(int i=1;i<=n;i++)

 81             for(int j=1;j<=n;j++)

 82                 dist[i][j]=inf;

 83         for(int i=1;i<=n;i++){

 84             scanf("%d",&gold[i]);

 85             total+=gold[i];

 86         }

 87         for(int i=1;i<=n;i++)scanf("%d",&store[i]);

 88         scanf("%d",&m);

 89         while(m--){

 90             scanf("%d%d%d",&a,&b,&c);

 91             dist[a][b]=dist[b][a]=c;

 92         }

 93         

 94         int low=0,high=100010,mid,ans=-1;

 95         while(low<=high){

 96             mid=(low+high)>>1;

 97             Build_Map(mid,n);

 98             if(Dinic()==total){

 99                 ans=mid;

100                 high=mid-1;

101             }else 

102                 low=mid+1;

103         }

104         if(ans==-1){

105             printf("No Solution\n");

106         }else 

107             printf("%d\n",ans);

108     }

109     return 0;

110 }

111 

112 

113         
View Code

 

你可能感兴趣的:(poj)