• A simple Gaussian elimination problem.


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

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

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

      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!
    ",tt++);
    126      else if(ans==1)
    127         printf("Case #%d: So simple!
    ",tt++);
    128      else
    129         printf("Case #%d: So young!
    ",tt++);
    130    }
    131 }
    View Code
  • 相关阅读:
    Linux安装zookeeper以及部署dubbo-admin
    springboot+layui+mybatis-plus的批量删除(批量修改)
    springboot打包jar与war包
    drf-books系列接口作业和分页器
    drf-过滤排序异常处理封装Response对象
    drf-认证权限频率
    drf-路由组件
    视图组件
    请求和响应
    Serializer和ModelSerializer
  • 原文地址:https://www.cnblogs.com/chujian123/p/3938887.html
Copyright © 2020-2023  润新知