题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2686
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 0x7fffffff 10 using namespace std; 11 const int maxn=20000+10; 12 const int M = 9999999; 13 14 int n,from,to; 15 struct node 16 { 17 int v,flow,cost; 18 int next; 19 }edge[M*3]; 20 int head[maxn],edgenum; 21 int dis[maxn],pre[maxn],pid[maxn],vis[maxn]; 22 int an[33][33]; 23 24 void add(int u,int v,int flow,int cost) 25 { 26 edge[edgenum].v=v ;edge[edgenum].flow=flow; 27 edge[edgenum].cost=cost ;edge[edgenum].next=head[u]; 28 head[u]=edgenum++; 29 30 edge[edgenum].v=u ;edge[edgenum].flow=0; 31 edge[edgenum].cost=-cost ;edge[edgenum].next=head[v]; 32 head[v]=edgenum++; 33 } 34 35 int spfa() 36 { 37 memset(vis,0,sizeof(vis)); 38 memset(dis,-1,sizeof(dis)); 39 queue<int> Q; 40 Q.push(from); 41 dis[from]=0; 42 vis[from]=1; 43 while (!Q.empty()) 44 { 45 int u=Q.front() ;Q.pop(); 46 vis[u]=0; 47 for (int i=head[u] ;i!=-1 ;i=edge[i].next) 48 { 49 int v=edge[i].v; 50 if (edge[i].flow>0 && dis[v]<dis[u]+edge[i].cost) 51 { 52 dis[v]=dis[u]+edge[i].cost; 53 pre[v]=u; 54 pid[v]=i; 55 if (!vis[v]) 56 { 57 vis[v]=1; 58 Q.push(v); 59 } 60 } 61 } 62 } 63 return dis[to]; 64 } 65 66 int mincost() 67 { 68 int aug=0,maxflow=0; 69 int ans=0; 70 int ncase=0; 71 while (1) 72 { 73 aug=inf; 74 int tmp=spfa(); 75 if (tmp==0) break; 76 for (int i=to ;i!=from ;i=pre[i]) 77 { 78 if (edge[pid[i] ].flow<aug) 79 aug=edge[pid[i] ].flow; 80 } 81 for (int i=to ;i!=from ;i=pre[i]) 82 { 83 edge[pid[i] ].flow -= aug; 84 edge[pid[i]^1 ].flow += aug; 85 } 86 ans += tmp; 87 ncase++; 88 if (ncase==2) break; 89 } 90 return ans-an[1][1]-an[n][n]; 91 } 92 93 int main() 94 { 95 while (scanf("%d",&n)!=EOF) 96 { 97 memset(head,-1,sizeof(head)); 98 edgenum=0; 99 for (int i=1 ;i<=n ;i++) 100 { 101 for (int j=1 ;j<=n ;j++) 102 scanf("%d",&an[i][j]); 103 } 104 from=1; 105 to=2*n*n; 106 for (int i=1 ;i<=n ;i++) 107 { 108 for (int j=1 ;j<=n ;j++) 109 { 110 int u=(i-1)*n+j; 111 int v=(i-1)*n+j+n*n; 112 add(u,v,1,an[i][j]); 113 if (j+1<=n) add(v,u+1,1,0); 114 if (i+1<=n) add(v,i*n+j,1,0); 115 } 116 } 117 add(from,from+n*n,1,an[1][1]); 118 add(n*n,to,1,an[n][n]); 119 int sum=mincost(); 120 printf("%d\n",sum); 121 } 122 return 0; 123 }