文理分班

来源:互联网 发布:php解析json数组 编辑:程序博客网 时间:2024/05/01 00:10

问题 D: 文理分班

时间限制: 1 Sec  内存限制: 256 M

题目描述

jzyz每年的文理分班的时候,每个班都会有一些同学分到其他班,还会进入一些其他班的同学进入这个班。

小x负责安排座位,为了照顾分班带来的那种伤感情绪,小x制定了很人性化的座位安排计划,具体计划如下:

比如A和B都是本班学生且是好朋友,A分到了其他班,而C则是外班进入这个班的,C和A并不熟悉,而C和B关系很好,那么小x为了照顾A和C的情绪,就会让B坐在A的位置,C坐在B的位置。

当然,实际情况可能很复杂,比如一个班里的同学之间关系不一定好,外班进来的可能和本班很多人关系都很好。

现在告诉你,和小x所在班有关系的人一共有n个人,小x想知道有没有一个合理的方案来满足自己的座位安排计划。


输入

本题为多组数据,第一行一个整数M,表示有M组测试数据。

对于每组测试数据,每组的第一行一个整数n,表示一共有n个人和这个班有关系。

接下来一行n个整数,第i个整数表示第i个人是否是本班学生(0表示不是,1表示是,分到其他班的也算是本班学生)

接下来一行n个整数,第i个整数表示第i个人是否要分到其他班(0表示留在本班,1表示分到其他班,如果第i个人是由外班分进来的,那么第i个整数就是一个随机整数,没有实际意义)

接下来是一个n行n列的一个二维矩阵,第i行第j列的数表示第i个人和第j个人是否关系很好(1表示认识,0表示不认识),对角线上是0,但是自己肯定认识自己。

输出

每组数据,如果存在一个方案,输出 “?_?”(不含引号)。

如果没有方案,输出 “T_T”(不含引号)。都是半角字符。

样例输入

131 1 00 1 00 1 11 0 01 0 0

样例输出

?_?

提示

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


宿舍流


#include <iostream>
#include <string.h>
#include <stdio.h>
#include<cmath>
using namespace std;
const int N=2505;
int a[N][N],x;
bool vis[N];
int link[N],head[N];
int s[N],b[N];
int cnt,n,m,k;
struct Edge
{
    int to;
    int next;
};
Edge edge[N*N];


void Init()
{
    cnt = 0;
    memset(head,-1,sizeof(head));
}


void add(int u,int v)
{
    edge[cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt++;
}


bool dfs(int u)
{
    for(int i=head[u];~i;i=edge[i].next)
    {
        int v = edge[i].to;
        if(!vis[v])
        {
            vis[v] = 1;
            if(link[v]==-1||dfs(link[v]))
            {
                link[v] = u;
                return true;
            }
        }
    }
    return false;
}
int match()
{
    int ans = 0;
    memset(link,-1,sizeof(link));
    for(int i=1;i<=n;i++)
    {
      if(!s[i]||s[i]&&!b[i])
      {
        memset(vis,0,sizeof(vis));
        if(!dfs(i))
        return false;
      }
    }
    return true;
}
int main()
{
    //freopen("in.txt","r",stdin);
   // freopen("zjoi09holiday.in","r",stdin);freopen("zjoi09holiday.out","w",stdout);
    cin>>m;
    while(m--)
    {
              int ans=0;
           scanf("%d",&n);
                Init();
            for(int i=1;i<=n;i++)
            {
              cin>>s[i];      
            }   
          for(int i=1;i<=n;i++)
            {
                  
                 cin>>b[i]; 
                 if(b[i]!=0&&b[i]!=1)
                 {
                 b[i]=0;
                 }  
                 
            } 
            for(int i=1;i<=n;i++)
             for(int j=1;j<=n;j++)
             {
               cin>>a[i][j];
               if(!s[j])a[i][j]=0;
               if((i==j&&s[i]==1&&b[i]==0)||a[i][j])add(i,j);
             }  
            if(match())cout<<"^_^"<<endl;
            else cout<<"T_T"<<endl;
            //if(w==ans)
            //else 
    }
//while(1);
    return 0;
}