题目描述
The Looksery company, consisting of nn 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 nnnumbers, 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.
(P.s感谢@luogu.org_悠悠我昕 提供翻译)
Looksery 公司由 n 名员工所组成,每个员工都有自己的电话和联系人列表。
最近,公司打算举办一场大型派对,每位到场的员工,都会向他的联系人发送消息,来说明这场派对有多炫酷。由于每个人都想花尽量多的时间来享受派对时光,他们会不假思索地向所有联系人发送消息,甚至包括他们自己。
Looksery 公司的开发者 Igor 和 Max 就每个人收到了多少条消息展开了争论. Igor 钦点了 n 个数字,其中第 i 个数字表示 Igor 认为第 i 个人收到的消息条数。如果 Igor 猜到了至少 1 个数字就算他胜利,否则 Max 胜利。
作为 Max 的支持者,你需要根据员工的联系人列表,确定是否存在 Igor 会输的情况。具体来说,你需要确定哪些人应该参加派对,使得派对结束后,任意一个人收到的消息条数与 Igor 所给出的不同。
输入输出格式
输入格式:
The first line contains a single integer nn ( 1<=n<=100 ) — the number of employees of company Looksery.
Next nn lines contain the description of the contact lists of the employees. The i -th of these lines contains a string of length nn , consisting of digits zero and one, specifying the contact list of the i -th employee. If the j -th character of the ii -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 ii -th character of the ii -th line is always equal tThe last line contains nn 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.
第一行一个正整数 n(1≤n≤100) ,表示 Looksery 公司的员工数量。
接下来 n 行描述了所有员工的联系人列表,每行为一个长度为 n 的字符串。若第 i 行的第 j 个字符为 1 ,则第 j名员工在第 i 名员工的联系人列表中,否则就不在。特别地,第 i 个人总是自己的联系人列表中。
最后一行 n 个由空格隔开的数字 a1,a2,...,an(0≤ai≤n) ,表示 Igor 所认为的每个员工会收到的消息数量。
输出格式:
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.
第一行一个整数 m 表示参加派对的人数。
第二行 m 个正整数,表示参加派对的员工的编号。
如果有多种方案满足条件,输出其中任意一种即可。
如果 Igor 无论如何都会赢,输出 -1 。
题解
对于这道题,我们可以先证明一下没有无解的情况:
【反证】假设存在无解情况,则存在当n个人都进入邀请方案时存在一个a[i] = 0,而这与a[i] = 0时才可以进入邀请方案相矛盾所以不存在无解情况。
由此我们可以考虑一下这道题的贪心策略:
如果不存在任何a[i]==0那么,当所有人都不进入邀请方案时一定满足条件。
如果存在某一a[i]!=0那么,因为如果i进入邀请方案,则他会给每一个他认识的人发送消息(包括他自己),这就可以使他收到的信息不为0,而同样他会更新其他他认识的人所不应该收到的短信数量,则会造成有新的a[k]==0只需要用队列记录一下,依次处理即可。
代码
#include <bits/stdc++.h> using namespace std; const int MAX = 105; vector<int> v[MAX], worker; queue<int> q; int a[MAX], vis[MAX]; int main() { // freopen("CF549B.in", "r", stdin); // freopen("CF549B.out", "w", stdout); int n, x; char s[MAX]; scanf("%d", &n); for(int i = 1; i <= n; ++ i) { scanf("%s", s + 1); for(int j = 1; j <= n; ++ j) if(s[j] == '1') v[i].push_back(j); } for(int i = 1; i <= n; ++ i) { scanf("%d", &a[i]); if(a[i] == 0) q.push(i); } for(;!q.empty();) { x = q.front(); q.pop(); worker.push_back(x); for(int i = 0; i < v[x].size(); ++ i) { int y = v[x][i]; a[y] --; if(a[y] == 0) q.push(y); } } printf("%d ", worker.size()); for(int i = 0; i < worker.size(); ++ i) printf("%d ", worker[i]); printf(" "); return 0; }
总结与反思
对于一些贪心我们通常的考虑是从一般情况入手,但是这道题他却需要我们构造出一组符合条件的特解,然后把大多数的一般情况都划归到这个特解上来,这是我们所需要了解的一种解题思路。