Codeforces 549B Looksery Party [贪心]

在Looksery公司的一次派对中,员工们通过发送消息给自己通讯录中的朋友分享派对的乐趣。本篇讨论如何确定哪些员工参加派对,使得每位员工收到的消息数量与预期不符,从而帮助Max在与Igor的赌约中获胜。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Looksery Party
Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u

Description
The Looksery company, consisting of n staff members, is planning another big party. Every employee has his phone number and the phone numbers of his friends in the phone book. Everyone who comes to the party, sends messages to his contacts about how cool it is. At the same time everyone is trying to spend as much time on the fun as possible, so they send messages to everyone without special thinking, moreover, each person even sends a message to himself or herself.

Igor and Max, Looksery developers, started a dispute on how many messages each person gets. Igor indicates n numbers, the i-th of which indicates how many messages, in his view, the i-th employee is going to take. If Igor guesses correctly at least one of these numbers, he wins, otherwise Max wins.

You support Max in this debate, so you need, given the contact lists of the employees, to determine whether there is a situation where Igor loses. Specifically, you need to determine which employees should come to the party, and which should not, so after all the visitors send messages to their contacts, each employee received a number of messages that is different from what Igor stated.

Input
The first line contains a single integer n (1 ≤ n ≤ 100) — the number of employees of company Looksery.

Next n lines contain the description of the contact lists of the employees. The i-th of these lines contains a string of length n, consisting of digits zero and one, specifying the contact list of the i-th employee. If the j-th character of the i-th string equals 1, then the j-th employee is in the i-th employee’s contact list, otherwise he isn’t. It is guaranteed that the i-th character of the i-th line is always equal to 1.

The last line contains n space-separated integers: a1, a2, …, an (0 ≤ ai ≤ n), where ai represents the number of messages that the i-th employee should get according to Igor.

Output
In the first line print a single integer m — the number of employees who should come to the party so that Igor loses the dispute.

In the second line print m space-separated integers — the numbers of these employees in an arbitrary order.

If Igor wins the dispute in any case, print -1.

If there are multiple possible solutions, print any of them.

Sample Input
Input
3
101
010
001
0 1 2
Output
1
1
Input
1
1
1
Output
0

Input
4
1111
0101
1110
0001
1 0 1 0
Output
4
1 2 3 4

Hint
In the first sample Igor supposes that the first employee will receive 0 messages. Since he isn’t contained in any other contact list he must come to the party in order to receive one message from himself. If he is the only who come to the party then he will receive 1 message, the second employee will receive 0 messages and the third will also receive 1 message. Thereby Igor won’t guess any number.

In the second sample if the single employee comes to the party he receives 1 message and Igor wins, so he shouldn’t do it.

In the third sample the first employee will receive 2 messages, the second — 3, the third — 2, the fourth — 3.

Source
Looksery Cup 2015


找出一种选取方案使得每个节点的入度都不等于Ai

  • 对于Ai==0的节点,如果选上它就可以保证 i 节点满足要求
  • 如果所有Ai!=0那么都不选就可以让所有的都满足要求

这样的话贪心就好了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#define AUTO "%I64d"
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
const int maxn = 105;
struct Edge
{
    int to,next;
}edge[maxn*maxn];
int head[maxn];
int maxedge;
inline void addedge(int u,int v)
{
    edge[++maxedge] = (Edge) { v,head[u] };
    head[u] = maxedge;
}
int a[maxn];
int ans[maxn];
int top;
int n;
bool vis[maxn];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("party.in","r",stdin);
    freopen("party.out","w",stdout);
#endif
    scanf("%d",&n);
    memset(head,-1,sizeof(head)); maxedge=-1;
    char ch;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            ch = getchar();
            while(!isdigit(ch)) ch=getchar();
            if(ch=='1') addedge(i,j);
        }
    for(int i=1;i<=n;i++) scanf("%d",a+i);
    while(true)
    {
        bool flag = false;
        for(int i=1;i<=n;i++) if(!a[i])
        {
            ans[++top] = i;
            vis[i] = true;
            flag = true;
            for(int j=head[i];~j;j=edge[j].next)
            {
                int v = edge[j].to;
                a[v]--;
            }
        }
        if(!flag) break;
    }
    printf("%d\n",top);
    for(int i=1;i<top;i++) printf("%d ",ans[i]);
    if(top) printf("%d",ans[top]);
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值