HDU 2676 Matrix

拆点跑费用流

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cstring>
  4 #include <queue>
  5 #define maxn 2010
  6 #define maxm 10100
  7 #define INF 1<<30
  8 using namespace std;
  9 struct MCMF{
 10     int src,sink,e,n;
 11     int first[maxn];
 12     int cap[maxm],cost[maxm],v[maxm],next[maxm];
 13     bool flag;
 14     void init(){
 15         e = 0;
 16         memset(first,-1,sizeof(first));
 17     }
 18 
 19     void add_edge(int a,int b,int cc,int ww){
 20         //printf("add:%d to %d,cap = %d,cost = %d\n",a,b,cc,ww);
 21         cap[e] = cc;cost[e] = ww;v[e] = b;
 22         next[e] = first[a];first[a] = e++;
 23         cap[e] = 0;cost[e] = -ww;v[e] = a;
 24         next[e] = first[b];first[b] = e++;
 25     }
 26 
 27     int d[maxn],pre[maxn],pos[maxn];
 28     bool vis[maxn];
 29 
 30     bool spfa(int s,int t){
 31         memset(pre,-1,sizeof(pre));
 32         memset(vis,0,sizeof(vis));
 33         queue<int> Q;
 34         for(int i = 0;i <= n;i++)   d[i] = INF;
 35         Q.push(s);pre[s] = s;d[s] = 0;vis[s] = 1;
 36         while(!Q.empty()){
 37             int u = Q.front();Q.pop();
 38             vis[u] = 0;
 39             for(int i = first[u];i != -1;i = next[i]){
 40                 if(cap[i] > 0 && d[u] + cost[i] < d[v[i]]){
 41                     d[v[i]] = d[u] + cost[i];
 42                     pre[v[i]] = u;pos[v[i]] = i;
 43                     if(!vis[v[i]])  vis[v[i]] = 1,Q.push(v[i]);
 44                 }
 45             }
 46         }
 47         return pre[t] != -1;
 48     }
 49 
 50     int Mincost;
 51     int Maxflow;
 52 
 53     int MinCostFlow(int s,int t,int nn){
 54         Mincost = 0,Maxflow = 0,n = nn;
 55         while(spfa(s,t)){
 56             int min_f = INF;
 57             for(int i = t;i != s;i = pre[i])
 58                 if(cap[pos[i]] < min_f) min_f = cap[pos[i]];
 59             Mincost += d[t] * min_f;
 60             Maxflow += min_f;
 61             for(int i = t;i != s;i = pre[i]){
 62                 cap[pos[i]] -= min_f;
 63                 cap[pos[i]^1] += min_f;
 64             }
 65         }
 66         return Mincost;
 67     }
 68 };
 69 MCMF g;
 70 
 71 int N;
 72 inline int id(int i,int j){
 73     return (i-1)*N + j;
 74 }
 75 
 76 int main(){
 77     while(scanf("%d",&N) != EOF){
 78         g.init();
 79         int k = N*N,ans = 0,a;
 80         int S = 0,T = 2*k+1;
 81         for(int i = 1;i <= N;i++){
 82             for(int j = 1;j <= N;j++){
 83                 scanf("%d",&a);
 84                 if(i+j == 2 || i+j == 2*N){
 85                     g.add_edge(id(i,j),id(i,j)+k,2,-a);
 86                     ans += a;
 87                 }else{
 88                     g.add_edge(id(i,j),id(i,j)+k,1,-a);
 89                 }
 90                 if(i < N)   g.add_edge(id(i,j)+k,id(i+1,j),1,0);
 91                 if(j < N)   g.add_edge(id(i,j)+k,id(i,j+1),1,0);
 92             }
 93         }
 94         g.add_edge(S,id(1,1),2,0);
 95         g.add_edge(id(N,N)+k,T,2,0);
 96         ans = -g.MinCostFlow(S,T,T) - ans;
 97         printf("%d\n",ans);
 98     }
 99     return 0;
100 }
View Code

 

posted @ 2013-10-14 19:08  浙西贫农  阅读(144)  评论(0编辑  收藏  举报