bzoj1433 [ZJOI2009]假期的宿舍(最大流)

1433: [ZJOI2009]假期的宿舍

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1717  Solved: 754
[Submit][Status][Discuss]

Description

   

Input

  

Output

 

Sample Input

1
3
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0

Sample Output

ˆ ˆ

HINT

对于30% 的数据满足1 ≤ n ≤ 12。
对于100% 的数据满足1 ≤ n ≤ 50,1 ≤ T ≤ 20。

Source

 

 

【思路】

       最大流。

       构图:

       1 每个人建立两个点u1,u2,建立s t点。

       2 如果需要床则s向u1连边,如果有床u2向t连边,如果认识u1向v2连边。

      

       Ps:总而言之,建图的思路就是要分配已有的床给需要床的人。

【代码】

 

 

  1 #include
  2 #include
  3 #include
  4 #include
  5 #define FOR(a,b,c) for(int a=(b);a<(c);a++)
  6 using namespace std;
  7 
  8 const int maxn = 500+10;
  9 const int INF = 1e9;
 10 
 11 struct Edge{
 12     int u,v,cap,flow;
 13 };
 14 struct Dinic {
 15     int n,m,s,t;
 16     bool vis[maxn];
 17     int d[maxn],cur[maxn];
 18     vector<int> G[maxn];
 19     vector es;
 20     
 21     void init(int n) {
 22         this->n=n;
 23         es.clear();
 24         for(int i=0;i) G[i].clear();
 25     }
 26     void AddEdge(int u,int v,int cap) {
 27         es.push_back((Edge){u,v,cap,0});
 28         es.push_back((Edge){v,u,0,0});
 29         m=es.size();
 30         G[u].push_back(m-2);
 31         G[v].push_back(m-1);
 32     }
 33     
 34     bool BFS() {
 35         queue<int> q;
 36         memset(vis,0,sizeof(vis));
 37         q.push(s); vis[s]=1; d[s]=0;
 38         while(!q.empty()) {
 39             int u=q.front(); q.pop();
 40             for(int i=0;i) {
 41                 Edge& e=es[G[u][i]];
 42                 int v=e.v;
 43                 if(!vis[v] && e.cap>e.flow) {
 44                     vis[v]=1;
 45                     d[v]=d[u]+1;
 46                     q.push(v);
 47                 }
 48             }
 49         }
 50         return vis[t];
 51     }
 52     int DFS(int u,int a) {
 53         if(u==t || a==0) return a;
 54         int flow=0,f;
 55         for(int& i=cur[u];i){
 56             Edge& e=es[G[u][i]];
 57             int v=e.v;
 58             if( d[v]==d[u]+1 && (f=DFS(v,min(a,e.cap-e.flow)))>0 ) {
 59                 e.flow+=f;
 60                 es[G[u][i]^1].flow-=f;
 61                 flow+=f,a-=f;
 62                 if(!a) break;
 63             }
 64         }
 65         return flow;
 66     }
 67     int Maxflow(int s,int t) {
 68         this->s=s , this->t=t;
 69         int flow=0;
 70         while(BFS()) {
 71             memset(cur,0,sizeof(cur));
 72             flow+=DFS(s,INF);
 73         }
 74         return flow;
 75     }
 76 } dc;
 77 
 78 int n,m;
 79 int f[maxn];
 80 
 81 int main() {
 82     int T;
 83     scanf("%d",&T);
 84     while(T--) {
 85         scanf("%d",&n);
 86         dc.init(n*2+2);
 87         int s=n*2,t=s+1;
 88         FOR(i,0,n) {
 89             scanf("%d",&f[i]);
 90             if(f[i]) dc.AddEdge(i+n,t,1);
 91         }
 92         int x,sum=0;
 93         FOR(i,0,n) {
 94             scanf("%d",&x);
 95             if((f[i]&&!x) || (!f[i])) {
 96                 dc.AddEdge(s,i,1);
 97                 sum++;
 98             }
 99         }
100         FOR(i,0,n) FOR(j,0,n) {
101             scanf("%d",&x);
102             if(x || i==j) dc.AddEdge(i,j+n,1);
103         }
104         int flow=dc.Maxflow(s,t);
105         if(flow==sum) printf("^_^\n");
106         else printf("T_T\n");
107     }
108     return 0;
109 }

 

你可能感兴趣的:(bzoj1433 [ZJOI2009]假期的宿舍(最大流))