Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 1372 | Accepted: 429 |
Description
Input
Output
Sample Input
2 3 2 bessie 2 3 bessie linda mary mary 1 1 linda linda 0 1 bessie 2 2 siavosh 1 2 siavosh mohammad mohammad 1 0
Sample Output
2 0
Source
/* 首先根据题目输入求出ia[]以及rel[][], ia[i]为1表示baker i初始时的chalk数为奇数,否则为 偶数, rel[i][j] = 1表示baker i 仰慕 baker j,那么第一次庆祝结束后的winner状态为: ia[] * rel[][] + ia[] = ia[] * (rel[][] + I[][]), I为单位矩阵,同理第二次后的状态为: ia[] * (rel[][] + I[][]) ^ 2,所以p次后的winner状态即为ia * (rel[][] + I[][]) ^ n; 所以整个问题就转换为了矩阵的快速幂运算。 矩阵的快速幂运算和求大数幂运算很像: 求res = A ^ p mod k, 先将p转为二进制,然后从低位向高位逐位计算,例如:p = 10110 则A ^ P mod k = {(A ^ 10) mod k) * (A ^ 100) mod k) * (A ^ 10000) mod k},在遍历的时候 可以用一个辅助矩阵expv记录(A ^ (2 ^ i)) mod k,每往上处理一位expv *= expv,如果p的当前位 为1则将res += expv mod k, 最后res即为结果 */ #include <iostream> #include <map> #include <string> #define MAX_N 105 using namespace std; int n, t, indexnum; struct matrix { int m[MAX_N][MAX_N]; }; int ia[MAX_N], res[MAX_N]; matrix rel; map<string, int> mapper; //计算a * b并将结果放在c中 a为s1 * s2矩阵,b为s2 * s3矩阵 matrix mult(const matrix &a, const matrix &b) { matrix res; memset(res.m, 0, sizeof(res.m)); for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) res.m[i][j] = (res.m[i][j] + a.m[i][k] * b.m[k][j]) % 2; return res; } //计算a的p次方并将结果放在a中 matrix pow(matrix a, int p) { matrix temp; int i; memset(temp.m, 0, sizeof(temp.m)); for(i = 0; i < n; i++) temp.m[i][i] = 1; while(p > 0) { if(p & 1) temp = mult(temp, a); a = mult(a, a); p>>=1; } return temp; } int solve() { int i, j, k; mapper.clear(); scanf("%d%d", &n, &t); memset(rel.m, 0, sizeof(rel.m)); memset(ia, 0, sizeof(ia)); indexnum = 0; string name; map<string, int>::iterator iter; int index1 = 0, index2 = 0; for(i = 0; i < n; i++) { cin>>name; if((iter = mapper.find(name)) == mapper.end()) mapper[name] = index1 = indexnum++; else index1 = iter->second; int relnum = 0; cin>>ia[index1]>>relnum; ia[index1] = ia[index1] % 2; for(j = 0; j < relnum; j++) { cin>>name; if((iter = mapper.find(name)) == mapper.end()) mapper[name] = index2 = indexnum++; else index2 = iter->second; rel.m[index1][index2] = (rel.m[index1][index2] + 1) % 2; } rel.m[index1][index1] = (rel.m[index1][index1] + 1) % 2; } //for(i = 0; i < n; i++) // rel.m[i][i] = (rel.m[i][i] + 1) % 2; rel = pow(rel, t - 1); memset(res, 0, sizeof(res)); for(i = 0; i < n; i++) for(j = 0; j < n; j++) res[i] = (res[i] + ia[j] * rel.m[j][i]) % 2; int total = 0; //统计winner的个数 for(i = 0; i < n; i++) if(res[i] == 1) total++; return total; } int main() { int caseN; cin>>caseN; while(caseN--) cout<<solve()<<endl; return 0; }