首页 > 代码库 > poj2391 Ombrophobic Bovines 拆点连边要注意

poj2391 Ombrophobic Bovines 拆点连边要注意

 

【题意】:给定F个牛棚和P条路径,每条路径有一个长度,现在每个牛棚有一定的容量和牛数,因为牛棚牛数可能大于容量,所以要牛棚之间的牛要进行相互地移动,每移动一个距离就花费一单位的时间,求从开始移动到每头牛都移动到牛棚的最小时间。

 

 一开始自己建图建错了,把每个点i拆成i‘和i‘‘,若i-->j有边 就i‘‘连j‘容量INF。再就是源点连每个i‘容量为INF,i’连i‘‘容量为牛数,j‘连j‘‘容量为牛棚容量,j‘‘连汇点容量为INF。

但是自己忽略了一点 若1->2->3,这是一条链,而1->2最短路为1,2->3为1,1->3为 2,此时如果我们限制最大距离为1的话,建的新图中必然有1->2,2->3, 新图中1和3也会间接的连接起来,而我们显然是不想这么让它流的。如果i->j这条边符合了距离限制,就加i‘->j‘‘  ,比如1->2->3这个例子,加的边是1’->2‘‘,2‘->3‘‘ 不会有流从1流到3去,因为加的每条边都流向了汇点。   见(http://blog.csdn.net/sdj222555/article/details/7771553)

 

此为TLE代码,先放这里

  1 #include<iostream>  2 #include<vector>  3 #include<string.h>  4 #include<queue>  5 #include<cstdio>  6 using namespace std;  7 #define INF 10000000  8 #define maxn 820  9  10 struct E{int from;int to;int c;int f;}; 11 vector <int> g[maxn]; 12 vector<E> edge; 13 int d[maxn],vis[maxn],cur[maxn],num[maxn],p[220],n,tot; 14  15 int dis[202][202],nz[202],you[202]; 16  17  18 void add(int from,int to,int c) 19 { 20     E temp1,temp2; 21     temp1.from =from; temp1.to=to; temp1.c=c;temp1.f=0; 22     temp2.from =to; temp2.to=from; temp2.c=0;temp2.f=0; 23     edge.push_back (temp1); 24     edge.push_back (temp2); 25     int m=edge.size (); 26     g[from].push_back (m-2); 27     g[to].push_back (m-1); 28 } 29  30 void bfs(int s,int t) 31 { 32     int i; 33     queue<int > q; 34     q.push (t); 35     d[t]=0; 36     memset(vis,0,sizeof(vis)); 37     vis[t]=1; 38     while(!q.empty ()) 39     { 40         int t=q.front ();q.pop (); 41         for(i=0;i<g[t].size ();i++) 42         { 43            E e;e=edge[g[t][i]]; 44            if(!vis[e.to]) 45            { 46                q.push (e.to); 47                vis[e.to]=1; 48                d[e.to]=d[t]+1; 49            } 50         } 51     } 52 } 53  54 int zg(int s,int t) 55 { 56     int x=t,a=INF; 57     while(x!=s) 58     { 59         //printf("x   %d\n",x); 60         E e=edge[p[x]]; 61         if(a>e.c-e.f) 62             a=e.c-e.f; 63         x=e.from; 64     } 65     x=t; 66     while(x!=s) 67     { 68         edge[p[x]].f+=a; 69         edge[p[x]^1].f-=a; 70         x=edge[p[x]].from ; 71     } 72     return a; 73 } 74  75 int maxflow(int s,int t,int n) 76 { 77     int flow=0,i; 78     bfs(s,t); 79     memset(num,0,sizeof(num)); 80     memset(cur,0,sizeof(cur)); 81     for(i=0;i<=t;i++) 82         num[d[i]]++; 83     int x=s; 84     while(d[s]<=n) 85     { 86         //printf("temp %d\n",flow); 87         if(x==t) 88         { 89             flow+=zg(s,t); 90             x=s; 91             //printf("flow  %d\n",flow); 92         } 93         int ok=0; 94         for(i=cur[x];i<g[x].size ();i++) 95         { 96             E e; 97             e=edge[g[x][i]]; 98             if(e.c>e.f&&d[x]==d[e.to]+1) 99             {100                 ok=1;101 102                 p[e.to]=g[x][i];103 104                 cur[x]=i;105                 x=e.to;//!@#$%^&106                 break;107             }108         }109         if(ok==0)110         {111             int m=n;112             for(i=0;i<g[x].size ();i++)113             {114                 E e;115                 e=edge[g[x][i]];116                 if(e.c>e.f&&m>d[e.to])117                     m=d[e.to];118             }119             if(--num[d[x]]==0)  break;120             num[d[x]=m+1]++;121             cur[x]=0;////!@#$%^^&122             if(x!=s)123                 x=edge[p[x]].from ;124 125         }126     }127     return flow;128 }129 130 bool ok(int x)131 {132     edge.clear();133     for(int i=0;i<=3*n+1;i++)134         g[i].clear();135 136     for(int i=1;i<=n;i++)137     {138         add(0,i,INF);139         add(i,i+n,you[i]);140         add(i+2*n,i+3*n,nz[i]);141         add(i+3*n,4*n+1,INF);142 143         for(int j=1;j<=n;j++)144             if(dis[i][j]<=x)145                  {146                      add(i,j+3*n,INF);147                      add(3*j+n,i,INF);148                  }149      }150     int flow;151     flow=maxflow(0,4*n+1,4*n+1);152     //printf("flow %d    x %d\n",flow,x);153     if(flow==tot)154         return true;155     return false;156 }157 158 int solve(int maxe)159 {160     int left=0,right=maxe,ans=maxe;161     while(left<=right)162     {163         int mid=(left+right)/2;164         if(ok(mid))165         {166             ans=min(ans,mid);167             right=mid-1;168         }169         else left=mid+1;170     }171     return ans;172 }173 174 int main()175 {176     int m,a,b,c;177     while(~scanf("%d%d",&n,&m))178     {179         tot=0;180         for(int i=1;i<=n;i++)181         {182             scanf("%d%d",&you[i],&nz[i]);183             tot+=you[i];184         }185         for(int i=1;i<=n;i++)186             for(int j=1;j<=n;j++)187                 if(i==j)188                 dis[i][j]=0;189             else190                dis[i][j]=INF;191         int size1=0;192         while(m--)193         {194             scanf("%d%d%d",&a,&b,&c);195             dis[a][b]=min(dis[a][b],c);196             dis[b][a]=min(dis[b][a],c);197         }198         int maxe=0;199         for(int k=1;k<=n;k++)200             for(int i=1;i<=n;i++)201                for(int j=1;j<=n;j++)202                {203                    dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]);204                    if(k==n)205                         maxe=max(maxe,dis[i][j]);206                }207         printf("%d\n",solve(maxe));208     }209     return 0;210 }

 

poj2391 Ombrophobic Bovines 拆点连边要注意