标签:des style blog http color java os io strong
http://acm.hdu.edu.cn/showproblem.php?pid=4975
3 1 1 5 5 2 2 0 10 0 10 2 2 2 2 2 2
Case #1: So simple! Case #2: So naive! Case #3: So young!
题目意思很简单:就是给出一个矩阵的行和和列和,矩阵中的每个元素都是0-9,问原矩阵是否存在,是否唯一;
分析:网络流求解,如果最大流=所有元素的和则有解;利用残留网络判断是否唯一,方法有两种,第一种是深搜看看是否存在正边权的环,至少3个点构成的环,第二种是用矩阵dp,假如某行的i列元素<9,j列元素>0,而另一行的i列元素>0,j列元素<9,那么答案不是唯一的,因为主对角线的 两个元素可以增大1,而副对角线的两个元素可以减小1,可以明显看出有多个答案;
比赛时的程序:
#include"stdio.h" #include"string.h" #include"iostream" #include"map" #include"string" #include"queue" #include"stdlib.h" #include"math.h" #define M 1900 #define eps 1e-10 #define inf 100000000 using namespace std; struct node { int u,v,w,next; }edge[600000]; int t,head[M],row[M],col[M],q[M],dis[M],work[M],use[M]; void init() { t=0; memset(head,-1,sizeof(head)); } void add(int u,int v,int w) { edge[t].u=u; edge[t].v=v; edge[t].w=w; edge[t].next=head[u]; head[u]=t++; edge[t].u=v; edge[t].v=u; edge[t].w=0; edge[t].next=head[v]; head[v]=t++; } int bfs(int S,int T) { int rear=0; memset(dis,-1,sizeof(dis)); dis[S]=0; q[rear++]=S; for(int i=0;i<rear;i++) { for(int j=head[q[i]];j!=-1;j=edge[j].next) { int v=edge[j].v; if(edge[j].w&&dis[v]==-1) { dis[v]=dis[q[i]]+1; q[rear++]=v; if(v==T) return 1; } } } return 0; } int dfs(int cur,int a,int T) { if(cur==T) return a; for(int &i=work[cur];i!=-1;i=edge[i].next) { int v=edge[i].v; if(edge[i].w&&dis[v]==dis[cur]+1) { int tt=dfs(v,min(a,edge[i].w),T); if(tt) { edge[i].w-=tt; edge[i^1].w+=tt; return tt; } } } return 0; } int Dinic(int S,int T) { int ans=0; while(bfs(S,T)) { memcpy(work,head,sizeof(head)); while(int tt=dfs(S,inf,T)) ans+=tt; } return ans; } int DFS(int u,int f) { use[u]=1; for(int &i=work[u];i!=-1;i=edge[i].next)//加&和复制的work数组 { int v=edge[i].v; if(edge[i].w&&v!=f) { if(use[v]) return 1; if(DFS(v,u)) return 1; } } use[u]=0; return 0; } int judge(int n,int m) { memset(use,0,sizeof(use)); memcpy(work,head,sizeof(head));//当初加了个这东西就莫名其妙的过了,并且很省时 for(int i=1;i<=n;i++) { if(DFS(i,i)) return 1; } return 0; } int main() { int n,m,i,j,kk=1; int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); int r=0,c=0; for(i=1;i<=n;i++) { scanf("%d",&row[i]); r+=row[i]; } for(j=1;j<=m;j++) { scanf("%d",&col[j]); c+=col[j]; } printf("Case #%d: ",kk++); if(r!=c) { printf("So naive!\n"); continue; } int flag=0; for(i=1;i<=n;i++) { if(m*9<row[i]) flag++; } for(i=1;i<=m;i++) { if(n*9<col[i]) flag++; } if(flag) { printf("So naive!\n"); continue; } init(); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { add(i,n+j,9); } } for(i=1;i<=n;i++) add(0,i,row[i]); for(j=1;j<=m;j++) add(j+n,m+n+1,col[j]); int ans=Dinic(0,m+n+1); if(ans<r) { printf("So naive!\n"); continue; } if(judge(n,m)) { printf("So young!\n"); continue; } printf("So simple!\n"); } return 0; }
#include"stdio.h" #include"string.h" #include"iostream" #include"map" #include"string" #include"queue" #include"stdlib.h" #include"math.h" #define M 1900 #define eps 1e-10 #define inf 1000000000 #define mod 2333333 using namespace std; struct node { int u,v,w,next; }edge[600000]; int t,head[M],work[M],use[M],dis[M],mp[555][555],G[555][555],row[555],col[555]; void init() { t=0; memset(head,-1,sizeof(head)); } void add(int u,int v,int w) { edge[t].u=u; edge[t].v=v; edge[t].w=w; edge[t].next=head[u]; head[u]=t++; edge[t].u=v; edge[t].v=u; edge[t].w=0; edge[t].next=head[v]; head[v]=t++; } int bfs(int S,int T) { memset(dis,-1,sizeof(dis)); queue<int>q; dis[S]=0; q.push(S); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(edge[i].w&&dis[v]==-1) { dis[v]=dis[u]+1; q.push(v); if(v==T) return 1; } } } return 0; } int dfs(int cur,int a,int T) { if(cur==T)return a; for(int &i=work[cur];i!=-1;i=edge[i].next) { int v=edge[i].v; if(edge[i].w&&dis[v]==dis[cur]+1) { int tt=dfs(v,min(edge[i].w,a),T); if(tt) { edge[i].w-=tt; edge[i^1].w+=tt; return tt; } } } return 0; } int Dinic(int S,int T) { int ans=0; while(bfs(S,T)) { memcpy(work,head,sizeof(head)); while(int tt=dfs(S,inf,T)) ans+=tt; } return ans; } int judge(int n,int m) { int k=0,i,j; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { G[i][j]=edge[k^1].w; k+=2; } } memset(mp,0,sizeof(mp)); for(i=1;i<=n;i++) { if(row[i]==0||row[i]==9*m)continue; for(j=1;j<=m;j++) { if(col[j]==0||col[j]==9*n)continue; for(k=j+1;k<=m;k++) { int f1=0,f2=0; if(G[i][j]<9&&G[i][k]>0) { if(mp[k][j]) return 1; f1++; } if(G[i][j]>0&&G[i][k]<9) { if(mp[j][k]) return 1; f2++; } if(f1)mp[j][k]=1; if(f2)mp[k][j]=1; } } } return 0; } int main() { int T,m,n,kk=1,i,j; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); int r=0; for(i=1;i<=n;i++) { scanf("%d",&row[i]); r+=row[i]; } int c=0; for(j=1;j<=m;j++) { scanf("%d",&col[j]); c+=col[j]; } printf("Case #%d: ",kk++); if(c!=r) { printf("So naive!\n"); continue; } int flag=0; for(i=1;i<=n;i++) if(9*m<row[i]) flag++; for(j=1;j<=m;j++) if(9*n<col[j]) flag++; if(flag) { printf("So naive!\n"); continue; } init(); int st=0; int sd=n+m+1; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { add(i,j+n,9); } } for(i=1;i<=n;i++) add(st,i,row[i]); for(j=1;j<=m;j++) add(j+n,sd,col[j]); int ans=Dinic(st,sd); if(ans!=r) { printf("So naive!\n"); continue; } if(judge(n,m)) { printf("So young!\n"); continue; } printf("So simple!\n"); } return 0; }
hdu4975 网络流解方程组(网络流+dfs判环或矩阵DP)
标签:des style blog http color java os io strong
原文地址:http://blog.csdn.net/mypsq/article/details/38756921