坐井观天

In the name of dream

导航

POJ2516 构图+k次费用流

Posted on 2012-06-22 14:31  一毛_  阅读(229)  评论(0编辑  收藏  举报

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

题目大意及分析:

  http://blog.csdn.net/lyy289065406/article/details/6742534

  这个题解非常非常详细,我的构图和他反了下,本质一样。

  这题KM的做法: http://blog.csdn.net/ChinaCzy/article/details/5813011

 

P.S. 这题我错了三天,三天来一直在搞这题,把网上一份和我的类似的代码找来改成我的风格,不断差错……

  不觉得把时间这样浪费是一种对生命的亵渎吗?区域赛说近也近了,三天可以做多少事啊!

 

1、我过去习惯的spfa的写法都是错误的,以后一律使用循环队列,且用 if( head==maxn ) head= 0; 更快!本题边权非负,所以不需要开cnt[]来记录是否有负环,既然是循环队列那么必须要用 while( head != tail )来结束循环而不是习惯性地 head<tail;

2、所谓费用流,是: 费用*流量,我忘记这一点就错了很久……

3、一定记得反边的边权是正向边边权的相反数;

4、这题开始我一直想不通那个k个物品怎么办,后来是看了题解才知道他们确实是独立的,要分别做费用流,可是我明明会这种费用流,为什么会错这么久呢? 我实在是不知道错在哪里了。

 

代码:

poj2516
  1 /*2516    Accepted    404K    266MS    C++    2635B    2012-06-22 14:08:10*/
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <vector>
  8 using namespace std;
  9 
 10 #define mpair make_pair
 11 #define pii pair<int,int>
 12 #define MM(a,b) memset(a,b,sizeof(a));
 13 typedef long long lld;
 14 typedef unsigned long long u64;
 15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
 16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
 17 #define maxn 110
 18 const int inf= 2100000000;
 19 
 20 int n,m,k;
 21 int ST, ED;
 22 int c[maxn][maxn], f[maxn][maxn];
 23 
 24 bool vis[maxn];
 25 int que[maxn+10], dis[maxn], pre[maxn];
 26 bool spfa(){
 27     for(int i=0;i<=ED;++i) dis[i]= inf, vis[i]= 0;
 28     int head= 0, tail= 0;
 29     que[tail++]= ST;
 30     vis[ST]= 1;
 31     dis[ST]= 0;
 32     while( head!=tail ){
 33         int u= que[head++];
 34         if( head==maxn ) head= 0;
 35         vis[u]= 0;
 36         for(int v=0;v<=ED;++v){
 37             if( f[u][v]>0 && up_min( dis[v], dis[u]+c[u][v] ) ){
 38                 pre[v]= u;
 39                 if( !vis[v] ){
 40                     que[tail++]= v;
 41                     if( tail==maxn ) tail= 0;
 42                     vis[v]= 1;
 43                 }
 44             }
 45         }
 46     }
 47     return dis[ED]!=inf;
 48 }
 49 
 50 int mincost(){
 51     int ret= 0;
 52     while( spfa() ){
 53         int t= inf;
 54         for(int i=ED;i!=ST;i=pre[i])
 55             up_min( t, f[ pre[i] ][i] );
 56         for(int i=ED;i!=ST;i=pre[i]){
 57             f[ pre[i] ][i] -= t;
 58             f[i][ pre[i] ] += t;
 59         }
 60         ret+= t*dis[ED];
 61     }
 62     return ret;
 63 }
 64 
 65 #define N 55
 66 int a[maxn][maxn], b[maxn][maxn];
 67 int solve(){
 68     int i,j;
 69     for(i=1;i<=n;++i)for(j=1;j<=k;++j)scanf("%d", &a[i][j]);
 70     for(i=1;i<=m;++i)for(j=1;j<=k;++j)scanf("%d", &b[i][j]);
 71 
 72     bool flag= 0;
 73     for(int p=1;p<=k;++p){
 74         int s1= 0, s2= 0;
 75         for(i=1;i<=n;++i) s1+= a[i][p];
 76         for(i=1;i<=m;++i) s2+= b[i][p];
 77         if( s1>s2 ){
 78             flag= 1; break;
 79         }
 80     }
 81 
 82     ST= 0, ED= n+m+1;
 83     int cost= 0;
 84     MM( c, 0 );
 85     for(int p=1;p<=k;++p){
 86         for(i=1;i<=n;++i)
 87             for(j=1;j<=m;++j){
 88                 scanf("%d", &c[i][n+j]);
 89                 c[n+j][i]= -c[i][n+j];
 90             }
 91         if( flag ) continue;
 92 
 93         MM( f, 0 );
 94         for(i=1;i<=n;++i) f[ST][i]= a[i][p];
 95         for(i=1;i<=m;++i) f[n+i][ED]= b[i][p];
 96         for(i=1;i<=n;++i)for(j=1;j<=m;++j)f[i][n+j]= inf;
 97         cost+= mincost();
 98     }
 99     if( flag ) cost= -1;
100     return cost;
101 }
102 
103 int main()
104 {
105     //freopen("poj2516.in","r",stdin);
106     while( cin>>n>>m>>k, n+m+k )
107         cout<< solve() <<endl;
108 }

 

poj2516_2
  1 /*2516    Accepted    400K    297MS    C++    2562B    2012-06-22 14:16:59*/
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <vector>
  8 using namespace std;
  9 
 10 #define mpair make_pair
 11 #define pii pair<int,int>
 12 #define MM(a,b) memset(a,b,sizeof(a));
 13 typedef long long lld;
 14 typedef unsigned long long u64;
 15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
 16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
 17 #define maxn 110
 18 const int inf= 2100000000;
 19 
 20 int n,m,k;
 21 int ST, ED;
 22 int c[maxn][maxn], f[maxn][maxn];
 23 
 24 bool vis[maxn];
 25 int que[maxn+10], dis[maxn], pre[maxn];
 26 bool spfa(){
 27     for(int i=0;i<=ED;++i) dis[i]= inf, vis[i]= 0;
 28     int head= 0, tail= 0;
 29     que[tail++]= ST;
 30     vis[ST]= 1;
 31     dis[ST]= 0;
 32     while( head!=tail ){
 33         int u= que[head++];
 34         if( head==maxn ) head= 0;
 35         vis[u]= 0;
 36         for(int v=0;v<=ED;++v){
 37             if( f[u][v]>0 && up_min( dis[v], dis[u]+c[u][v] ) ){
 38                 pre[v]= u;
 39                 if( !vis[v] ){
 40                     que[tail++]= v;
 41                     if( tail==maxn ) tail= 0;
 42                     vis[v]= 1;
 43                 }
 44             }
 45         }
 46     }
 47     return dis[ED]!=inf;
 48 }
 49 
 50 pii mincost(){
 51     int flow= 0, cost= 0;
 52     while( spfa() ){
 53         int t= inf;
 54         for(int i=ED;i!=ST;i=pre[i])
 55             up_min( t, f[ pre[i] ][i] );
 56         flow+= t;
 57         for(int i=ED;i!=ST;i=pre[i]){
 58             f[ pre[i] ][i] -= t;
 59             f[i][ pre[i] ] += t;
 60         }
 61         cost+= t*dis[ED];
 62     }
 63     return pii( flow, cost );
 64 }
 65 
 66 #define N 55
 67 int a[maxn][maxn], b[maxn][maxn];
 68 int solve(){
 69     ST= 0, ED= n+m+1;
 70     int i,j,cost= 0;
 71     for(i=1;i<=n;++i)for(j=1;j<=k;++j)scanf("%d", &a[i][j]);
 72     for(i=1;i<=m;++i)for(j=1;j<=k;++j)scanf("%d", &b[i][j]);
 73 
 74     bool flag= 0;
 75     MM( c, 0 );
 76     for(int p=1;p<=k;++p){
 77         MM( f, 0 );
 78         int ss= 0;
 79         for(i=1;i<=n;++i){
 80             ss+= a[i][p];
 81             for(j=1;j<=m;++j){
 82                 scanf("%d", &c[i][n+j]);
 83                 c[n+j][i]= -c[i][n+j];
 84                 f[i][n+j]= inf;
 85             }
 86         }
 87         if( flag ) continue;
 88 
 89         for(i=1;i<=n;++i) f[ST][i]= a[i][p];
 90         for(i=1;i<=m;++i) f[n+i][ED]= b[i][p];
 91         pii tmp= mincost();
 92         cost+= tmp.second;
 93         if( ss!=tmp.first ) flag= 1;
 94     }
 95     if( flag ) cost= -1;
 96     return cost;
 97 }
 98 
 99 int main()
100 {
101     //freopen("poj2516.in","r",stdin);
102     while( cin>>n>>m>>k, n+m+k )
103         cout<< solve() <<endl;
104 }