poj2345Central heating(高斯消元)

Central heating
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 724 Accepted: 335

Description

Winter has come, but at the Ural State University heating is not turned on yet. There's one little problem: the University is heated only if all of the valves are opened. There are some technicians at the University. Each of them is responsible for one or more valves. There may be several technicians responsible for the same valve. When a technician gets an instruction to turn on the heating he goes round all of his valves and turns them. It means that if a valve was opened then he closes it, and if it was closed then he opens it. It is well known that every technician earns his money not in vain so it's impossible to replace any technician by any combination of other technicians. 
Your task is to determine who of the technicians is to get an instruction "to turn on the heating" in order to heat all the Ural State University. Note that there are N technicians and N valves at the University (1 <= N <= 250). 

Input

The first line of an input contains the number N. The next N lines contain lists of the valves in charge of each of the technicians. It means that a line number i + 1 contains numbers of the valves that the i-th technician is responsible for. Each list of valves is followed by –1.

Output

An output should contain a list of technicians' numbers sorted in ascending order. If several lists are possible, you should send to an output the shortest one. If it's impossible to turn on the heating at the University, you should write "No solution" .

Sample Input

4
1 2 -1
2 3 4 -1
2 -1
4 -1

Sample Output

1 2 3

思路:根据每个人按一次就转换状态,然后最终状态为开着的,列出方程

代码:

#include<iostream>
#include<stdio.h>
#include<cmath>
#include<string.h>
using namespace std;
int n;
bool a[255][255],x[255];
int gauss()
{
    int maxn;
    for(int i=0,j=0;i<n&&j<n;i++,j++)
    {
        maxn=i;
        if(!a[maxn][j])
        {
            for(int k=i+1;k<n;k++)
            {
                if(a[k][j])
                {
                    maxn=k;
                    break;
                }
            }
        }
        if(!a[maxn][j])return 0;
        if(i!=maxn)
        {
            for(int z=j;z<n;z++)
            {
                swap(a[i][z],a[maxn][z]);
            }
            swap(x[i],x[maxn]);
        }
        for(int k=0;k<n;k++)
        {
            if(k!=i&&a[k][j])
            {
                x[k]^=x[i];
                for(int z=j+1;z<n;z++)
                {
                    a[k][z]^=a[i][z];
                }
                a[k][j]=0;
            }
        }
    }
    return 1;
}
int main()
{

    while(~scanf("%d",&n))
    {
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            int d;
            while(scanf("%d",&d)&&d!=-1)
            {
                a[d-1][i]=1;
            }
        }
        for(int i=0;i<n;i++)
            x[i]=true;
        gauss();
        for(int i=0;i<n;i++)
        {
            if(x[i])cout<<i+1<<' ';
        }
        cout<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值