只看题目的话~~怎么也看不出来是网络流的题目的说啊~~~~
建图好神奇~~
最开始不懂---后来看了一下这篇--
http://www.cnblogs.com/AOQNRMGYXLMV/p/4280727.html
建立源点 st = 0,汇点 ed = r+c
因为正整数的范围是1到20,而流量可以是0,所以先将矩阵里面的每个数减去1,到最后输出答案的时候再加上1
把每一行看做一个节点 x,编号为1到r
把每一列看做一个节点y,编号为r+1到r+c
st到x连边,容量为 Ai ‘- c
y到ed连边,容量为Bi‘ - r
x到y连边,容量为19
这样再用一下 dinic
节点xi到yj的流量就是格子(i,j) - 1之后的值
这句话最开始非常非常的不理解-------
后来搜了下题解
因为yj的流量来自于各个x
同样的,xi的流量流向各个y,所以(i,j)这个格子的流量来源是xi
大概像这个图这样
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 8 const int maxn = 10005; 9 const int INF = (1 << 30) - 1; 10 11 struct Edge{ 12 int v,next,c; 13 }e[maxn]; 14 15 int st,ed,lev[maxn],first[maxn],now[maxn],ecnt; 16 int r,c; 17 18 void init(){ 19 memset(first,-1,sizeof(first)); 20 ecnt = 0; 21 } 22 23 void addedges(int u,int v,int c){ 24 e[ecnt].next = first[u]; 25 e[ecnt].v = v; 26 e[ecnt].c = c; 27 first[u] = ecnt++; 28 29 e[ecnt].next = first[v]; 30 e[ecnt].v = u; 31 e[ecnt].c = 0; 32 first[v] = ecnt++; 33 } 34 35 bool bfs(){ 36 queue<int> q; 37 while(!q.empty()) q.pop(); 38 q.push(st); 39 memset(lev,-1,sizeof(lev)); 40 lev[st] = 0; 41 while(!q.empty()){ 42 int x = q.front();q.pop(); 43 for(int i = first[x];~i;i = e[i].next){ 44 int v = e[i].v; 45 if(lev[v] < 0 && e[i].c > 0){ 46 lev[v] = lev[x] + 1; 47 q.push(v); 48 } 49 } 50 } 51 return lev[ed] != -1; 52 } 53 54 int dfs(int p,int minf){ 55 if(p == ed || minf == 0) return minf; 56 for(int &i = now[p];~i;i = e[i].next){ 57 int v = e[i].v; 58 if(lev[v] == lev[p] + 1 && e[i].c > 0){ 59 int d = dfs(v,min(e[i].c,minf)); 60 if(d > 0){ 61 e[i].c -= d; 62 e[i^1].c += d; 63 return d; 64 } 65 } 66 } 67 return 0; 68 } 69 70 int dinic(){ 71 int max_flow = 0,p1; 72 while(bfs()){ 73 memcpy(now,first,sizeof(first)); 74 while((p1 = dfs(st,INF)) > 0) 75 max_flow += p1; 76 } 77 return max_flow; 78 } 79 80 int ans[55][55]; 81 82 int main(){ 83 int T; 84 scanf("%d",&T); 85 int kase = 0; 86 while(T--){ 87 scanf("%d %d",&r,&c); 88 init(); 89 st = 0;ed = r+c+1; 90 91 int last = 0,cur; 92 for(int i = 1;i <= r;i++){ 93 scanf("%d",&cur); 94 addedges(st,i,cur-last-c); 95 last = cur; 96 } 97 98 last = 0; 99 for(int i = 1;i <= c;i++){ 100 scanf("%d",&cur); 101 addedges(i + r,ed,cur-last-r); 102 last = cur; 103 } 104 105 for(int i = 1;i <= r;i++) 106 for(int j = 1;j <= c;j++) addedges(i,j+r,19); 107 108 int res = dinic(); 109 110 for(int u = 1;u <= r;u++){ 111 for(int i = first[u];~i;i = e[i].next){ 112 int v = e[i].v; 113 ans[u][v-r] = 19 - e[i].c; 114 } 115 } 116 117 printf("Matrix %d\n",++kase); 118 for(int i = 1;i <= r;i++){ 119 printf("%d",ans[i][1] + 1); 120 for(int j = 2;j <= c;j++) 121 printf(" %d",ans[i][j] + 1); 122 printf("\n"); 123 } 124 if(T) puts(""); 125 } 126 return 0; 127 }
时间: 2024-11-05 13:59:26