标签:style blog http color os io for div cti
http://acm.hdu.edu.cn/showproblem.php?pid=4975
题意:同HDU 4888。给N行M列,每行之和,每列之和,判断矩阵是不是唯一。
题解:网络流。源点和每行之和建边,容量为和;汇点和没列之和建边,容量为和;行之和和列之和建边,容量为9(每位只能是0~9)。
判断可行性:行之和的和是否等于列之和的和;是否满流。
判断唯一解:残留网络里是否有长度大于等于2的环
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cstdlib> 5 #include <string> 6 #include <algorithm> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <queue> 11 #include <stack> 12 #include <cmath> 13 #include <ctime> 14 #include <functional> 15 #include <cctype> 16 17 using namespace std; 18 19 typedef __int64 ll; 20 21 const int INF=0xfffffff; 22 23 const int maxm=500*500*10+10; 24 const int maxn=510+510; 25 26 struct edge{ 27 int to,cap,next; 28 edge(int to=0,int cap=0,int next=0):to(to),cap(cap),next(next){} 29 }G[maxm]; 30 int head[maxn],level[maxn]; 31 bool used[maxn]; 32 int g[maxn][maxn]; 33 int sumr,sumc; 34 int N,M; 35 int flag; 36 int idx; 37 int s,t; 38 39 void add_edge(int from,int to,int cap) 40 { 41 G[++idx]=edge(to,cap,head[from]); 42 head[from]=idx; 43 G[++idx]=edge(from,0,head[to]); 44 head[to]=idx; 45 } 46 47 bool bfs(int S,int T) 48 { 49 memset(level,0xff,sizeof(level)); 50 level[S]=0; 51 queue<int> q; 52 q.push(S); 53 while(!q.empty()) 54 { 55 int v=q.front(); 56 q.pop(); 57 for(int k=head[v];k!=-1;k=G[k].next) 58 { 59 edge &e=G[k]; 60 if(level[e.to]==-1&&e.cap){ 61 level[e.to]=level[v]+1; 62 q.push(e.to); 63 } 64 } 65 } 66 return level[T]!=-1; 67 } 68 69 int dfs(int v,int f,int T) 70 { 71 if(v==T||f==0) return f; 72 int flow=0; 73 for(int k=head[v];k!=-1;k=G[k].next) 74 { 75 edge &e=G[k]; 76 if(level[e.to]==level[v]+1){ 77 int d; 78 if((d=dfs(e.to,min(f,e.cap),T))>0){ 79 G[k].cap-=d; 80 G[k^1].cap+=d; 81 flow+=d; 82 f-=d; 83 if(f==0) return flow; 84 } 85 } 86 } 87 level[v]=-1; 88 return flow; 89 } 90 91 int max_flow(int s,int t) 92 { 93 int flow=0; 94 int f; 95 while(bfs(s,t)==1) 96 { 97 while((f=dfs(s,INF,t))>0) 98 { 99 flow+=f; 100 } 101 } 102 return flow; 103 } 104 105 int dfs_loop(int u,int rev) 106 { 107 for(int &k=head[u];k!=-1;k=G[k].next) 108 { 109 if(k==(rev^1)) continue; 110 if(G[k].cap){ 111 if(used[G[k].to]) return 1; 112 used[G[k].to]=true; 113 if(dfs_loop(G[k].to,k)==1) return 1; 114 used[G[k].to]=false; 115 } 116 } 117 return 0; 118 } 119 120 int judge() 121 { 122 for(int i=1;i<=N;i++) 123 { 124 if(dfs_loop(i,-1)) return 0; 125 } 126 return 1; 127 } 128 129 void init() 130 { 131 idx=-1; 132 memset(head,0xff,sizeof(head)); 133 memset(used,0,sizeof(used)); 134 sumr=0; 135 sumc=0; 136 flag=0; 137 } 138 139 int main() { 140 int T; 141 scanf("%d",&T); 142 for(int ca=1;ca<=T;ca++) 143 { 144 init(); 145 printf("Case #%d: ",ca); 146 scanf("%d%d",&N,&M); 147 s=0; 148 t=N+M+1; 149 int cr; 150 for(int i=1;i<=N;i++) 151 { 152 scanf("%d",&cr); 153 sumr+=cr; 154 add_edge(s,i,cr); 155 for(int j=1;j<=M;j++) 156 { 157 add_edge(i,N+j,9); 158 } 159 } 160 int cc; 161 for(int i=1;i<=M;i++) 162 { 163 scanf("%d",&cc); 164 sumc+=cc; 165 add_edge(N+i,t,cc); 166 } 167 int maxflow=max_flow(s,t); 168 if(sumr!=sumc) puts("So naive!"); 169 else if(sumr!=maxflow) puts("So naive!"); 170 else if(!judge()) puts("So young!"); 171 else puts("So simple!"); 172 } 173 return 0; 174 }
HDU 4975 A simple Gaussian elimination problem.
标签:style blog http color os io for div cti
原文地址:http://www.cnblogs.com/der-z/p/3930723.html