码迷,mamicode.com
首页 > 其他好文 > 详细

A simple Gaussian elimination problem.

时间:2014-08-27 12:22:57      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   ar   art   

hdu4975:http://acm.hdu.edu.cn/showproblem.php?pid=4975

题意:给你一个n*m的矩阵,矩阵中的元素都是0--9,现在给你这个矩阵的每一行和每一列的和,问你这个矩阵是否存在,唯一,或者不唯一。

题解:这一题就是用传说中的网络流破解。首先建图就是把每一行和每一列看成一个点,行和源点建立一条边,容量为这一行的和,列和汇点建边,容量是这一列的和,然后每一行和每一列建立一边,容量是9.然后跑网络流,如果流量和总和相等,说明有解,然后用判断是否唯一,题解中就是说要判断是否存在环,这里用到了类似tarjan的方法判断是否有环。

bubuko.com,布布扣
  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cstdio>
  5 #include<queue>
  6 #define INF 100000000
  7 using namespace std;
  8 const int N=3005;
  9 const int M=2000000;
 10 struct Node{
 11    int v;
 12    int f;
 13    int next;
 14 }edge[M];
 15 int n,m,u,v,cnt,sx,ex;
 16 int head[N],pre[N];
 17 bool vis[N],no[N];
 18 int st[N],top;//根据题目要求申请
 19 void init(){
 20     cnt=0;
 21     memset(head,-1,sizeof(head));
 22     memset(vis,0,sizeof(vis));
 23     memset(no,0,sizeof(no));
 24 }
 25 void add(int u,int v,int w){
 26     edge[cnt].v=v;
 27     edge[cnt].f=w;
 28     edge[cnt].next=head[u];
 29     head[u]=cnt++;
 30     edge[cnt].f=0;
 31     edge[cnt].v=u;
 32     edge[cnt].next=head[v];
 33     head[v]=cnt++;
 34 }
 35 bool BFS(){
 36   memset(pre,0,sizeof(pre));
 37   pre[sx]=1;
 38   queue<int>Q;
 39   Q.push(sx);
 40  while(!Q.empty()){
 41      int d=Q.front();
 42      Q.pop();
 43      for(int i=head[d];i!=-1;i=edge[i].next    ){
 44         if(edge[i].f&&!pre[edge[i].v]){
 45             pre[edge[i].v]=pre[d]+1;
 46             Q.push(edge[i].v);
 47         }
 48      }
 49   }
 50  return pre[ex]>0;
 51 }
 52 int dinic(int flow,int ps){
 53     int f=flow;
 54      if(ps==ex)return f;
 55      for(int i=head[ps];i!=-1;i=edge[i].next){
 56         if(edge[i].f&&pre[edge[i].v]==pre[ps]+1){
 57             int a=edge[i].f;
 58             int t=dinic(min(a,flow),edge[i].v);
 59               edge[i].f-=t;
 60               edge[i^1].f+=t;
 61             flow-=t;
 62              if(flow<=0)break;
 63         }
 64      }
 65       if(f-flow<=0)pre[ps]=-1;
 66       return f-flow;
 67 }
 68 int solve(){
 69     int sum=0;
 70     while(BFS())
 71         sum+=dinic(INF,sx);
 72     return sum;
 73 }
 74 bool dfs(int u,int pre,bool flag){
 75     vis[u] = 1;
 76     st[top++] = u;
 77     for(int i = head[u];i != -1;i = edge[i].next){
 78         int v = edge[i].v;
 79         if(edge[i].f<=0)continue;
 80         if(v == pre)continue;
 81         if(!vis[v]){
 82             if(dfs(v,u,edge[i^1].f >0))return true;
 83         }
 84         else if(!no[v])return true;
 85     }
 86     if(!flag){
 87         while(1){
 88             int v = st[--top];
 89             no[v] = true;
 90             if(v == u)break;
 91         }
 92     }
 93     return false;
 94 }
 95 int main(){
 96    int T,sumc,sumr,ans,temp,tt=1;
 97    scanf("%d",&T);
 98    while(T--){
 99       scanf("%d%d",&n,&m);
100       init();
101       ans=1,sumc=sumr=0;sx=0;ex=n+m+1;
102       for(int i=1;i<=n;i++){
103           scanf("%d",&temp);
104           add(sx,i,temp);
105           sumr+=temp;
106           for(int j=1;j<=m;j++)
107             add(i,j+n,9);
108       }
109       for(int i=1;i<=m;i++){
110           scanf("%d",&temp);
111           add(i+n,ex,temp);
112           sumc+=temp;
113       }
114       top=0;
115       if(sumr!=sumc){
116           ans=0;
117       }
118       else if(sumr!=solve()){
119          ans=0;
120       }
121      else if(dfs(n+m+1,n+m+1,0)){
122          ans=2;
123      }
124      if(ans==0)
125         printf("Case #%d: So naive!\n",tt++);
126      else if(ans==1)
127         printf("Case #%d: So simple!\n",tt++);
128      else
129         printf("Case #%d: So young!\n",tt++);
130    }
131 }
View Code

 

A simple Gaussian elimination problem.

标签:style   blog   http   color   os   io   for   ar   art   

原文地址:http://www.cnblogs.com/chujian123/p/3938887.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!