hdu 4975A simple Gaussian elimination problem. 最大流

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std ;
const int maxn = 1010 ;
#define inf 0x3fffffff
int dis[maxn] ;
int vis[maxn] ;
int work[maxn] ;
int st = 0 ;
int en = 1001 ;
struct Edge
{
    int u , v , w ;
    int next ;
}edge[maxn*maxn*4] ;
int head[maxn] ;
int nedge = 0 ;
void addedge(int u , int v , int w)
{
    edge[nedge].v = v ;
    edge[nedge].w = w ;
    edge[nedge].next = head[u] ;
    head[u] = nedge++ ;
    edge[nedge].v = u ;
    edge[nedge].w = 0 ;
    edge[nedge].next = head[v] ;
    head[v] = nedge++ ;
}
bool bfs()
{
    queue<int> que ;
    memset(dis , -1 ,sizeof(dis)) ;
    dis[st] = 0 ;
    que.push(st) ;
    while(que.size())
    {
        int u = que.front() ;
        que.pop() ;
        for(int i = head[u]; i != -1 ; i = edge[i].next)
        {
            int v = edge[i].v ;
            if(edge[i].w > 0 && dis[v] < 0)
            {
                dis[v] = dis[u] + 1 ;
                que.push(v) ;
            }
        }
    }
    if(dis[en] > 0)
    return true ;
    return false ;
}
int dfs(int x,int mx)
{
    if(x==en)
    return mx;
    int ans=0;
    int a;
    for(int &i=work[x];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(dis[v]==dis[x]+1&&edge[i].w>0&&(a=dfs(v,min(mx,edge[i].w))))
        {
            edge[i].w -= a;
            edge[i^1].w += a;
            ans += a;
            mx -= a;
            if(!mx)
            break;
        }
    }
    if(!ans)
    dis[x] = -1; 
    return ans;
}
bool dfss(int u,int pre )
{
   vis[u] = 1 ;
   for(int &i = work[u];i != -1;i = edge[i].next){
        int v = edge[i].v;
        if(v == pre || v == en || v == st||edge[i].w <= 0)
        continue ;
        if(vis[v])return true ;
        if(dfss(v,u))
        return true ;
    }
    vis[u] = 0 ;
    return false ;
}
int main()
{
    int t ;
    int cas =  0;
    scanf("%d" , &t) ;
    while(t--)
    {
        int n ,m;
        memset(head , -1 , sizeof(head)) ;
        memset(vis, 0 ,sizeof(vis)) ;
        nedge = 0 ;
        scanf("%d%d" , &n,&m) ;
        st = 0 ; en = n + m + 1 ;
        int sum1 = 0 , sum2 = 0 ;
        for(int i = 1;i <= n;i++){
            int x ;
            scanf("%d" , &x) ;
            sum1 += x ;
            addedge(st,i,x) ;
        }
        for(int j = 1;j <= m;j++){
            int y ;
            scanf("%d" , &y) ;
            sum2 += y ;
            addedge(n+j,en,y) ;
        }
        printf("Case #%d: " , ++cas) ;
        if(sum1 != sum2){
            puts("So naive!") ;
            continue ;
        }
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= m;j++)
               addedge(i,n+j,9) ;
        int res , ans = 0 ;
        while(bfs()){
            memcpy(work , head , sizeof(head)) ;
            while(res = dfs(st,inf))
              ans += res ;
        }
        if(ans == sum1){
           bool flag = false;
           memcpy(work,head,sizeof(head)) ;
           for(int i = 0;i <= n;i++){
               if(dfss(i , -1)){
                  flag = true ;
                  break ;
               }
           }
           if(flag){
               puts("So young!") ;
           }
           else puts("So simple!") ;
        }
        else puts("So naive!") ;
    }
}

你可能感兴趣的:(hdu 4975A simple Gaussian elimination problem. 最大流)