tjut 4975

来源:互联网 发布:考勤机更改下载数据 编辑:程序博客网 时间:2024/06/08 14:36
#include <queue>  #include <vector>  #include <stdio.h>  #include <stdlib.h>  #include <string.h>  #include <iostream>  using namespace std;  const int INF=0x3f3f3f3f;  struct node{      int u,v,cap;      node(){}      node(int u,int v,int cap):u(u),v(v),cap(cap){}  }es[1000005];  int R,S,T;  int dis[50005],vis[50005],iter[50005];  vector<int> tab[50005];  vector<int> G[50005];  void addedge(int u, int v, int cap){      tab[u].push_back(R);      es[R++]=node(u,v,cap);      tab[v].push_back(R);      es[R++]=node(v,u,0);  }  int bfs(){      int i,h;      queue<int> q;      q.push(S);      memset(dis,INF,sizeof(dis));      dis[S]=0;      while(q.size()){          h=q.front();          q.pop();          for(i=0;i<tab[h].size();i++){              node &e=es[tab[h][i]];              if(e.cap>0&&dis[e.v]==INF){                  dis[e.v]=dis[h]+1;                  q.push(e.v);              }          }      }      return dis[T]<INF;  }  int dfs(int x,int maxflow){      int flow;      if(x==T)      return maxflow;      for(int &i=iter[x];i<tab[x].size();i++){          node &e=es[tab[x][i]];          if(dis[e.v]==dis[x]+1&&e.cap>0){              flow=dfs(e.v,min(maxflow,e.cap));              if(flow){                  e.cap-=flow;                  es[tab[x][i]^1].cap+=flow;                  return flow;              }          }      }      return 0;  }  int dinic(){      int ans,flow;      ans=0;      while(bfs()){          memset(iter,0,sizeof(iter));          while(flow=dfs(S,INF))          ans+=flow;      }      return ans;  }                                               //dinic模板  int judge(int s,int t){      int i,tmp;      vis[s]=1;      for(i=0;i<G[s].size();i++){          tmp=G[s][i];          if(tmp==t)                              //防止出现两个节点的环          continue;                 if(vis[tmp]==1)          return 1;          if(judge(tmp,s))          return 1;      }      vis[s]=0;      return 0;  }  int main(){      int N,M,i,j,l,r,t,ans,cas,num,sign;      cas=1;      scanf("%d",&t);      while(t--){                                 //以行和列建立二分图跑网络流          scanf("%d%d",&N,&M);          l=r=0;          S=0,R=0,T=N+M+1;          for(i=0;i<=T;i++){          G[i].clear();          tab[i].clear();          }          memset(vis,0,sizeof(vis));          for(i=1;i<=N;i++){              scanf("%d",&num);              addedge(S,i,num);              l+=num;          }          for(i=1;i<=M;i++){              scanf("%d",&num);              addedge(i+N,T,num);              r+=num;          }          for(i=1;i<=N;i++)          for(j=1;j<=M;j++)          addedge(i,j+N,9);                       //因为只能0~9所以容量建为9          if(l!=r){                               //如果行的和和列的和不相等则一定无解              printf("Case #%d: So naive!\n",cas++);              continue;          }          ans=dinic();          if(ans!=l){                             //不是满流的也无解              printf("Case #%d: So naive!\n",cas++);              continue;          }          for(i=0;i<R;i++)          if(es[i].cap>0)                         //将残余网络保存下来判断是否有环,从而          G[es[i].u].push_back(es[i].v);          //确定是否有多组解,因为当残余网络中有          sign=0;                                 //环时则可以通过残余网络去跑一些原来的流量          for(i=1;i<=N;i++)          if(judge(i,-1)){              sign=1;              break;          }          if(sign)          printf("Case #%d: So young!\n",cas++);          else          printf("Case #%d: So simple!\n",cas++);      }      return 0; }

0 0
原创粉丝点击