您的位置:首页 > 其它

2014百度之星初赛第一轮解题报告:CycleCocycle

2014-05-27 22:02 375 查看
[align=left]CycleCocycle[/align]
[align=left]时间限制:10s 内存限制:64MB[/align]
[align=left][/align]
[align=left]问题描述[/align]
[align=left]有一个n个点m条边的图,你要给每个点一个0或1的标号,使得每个点与偶数个相同标号的点之间有边。如果有多解输出任意一组。[/align]
[align=left][/align]
[align=left]输入[/align]
[align=left]第一行为T,表示输入数据组数。[/align]
[align=left]下面T组数据。每组数据中:[/align]
[align=left]第一行,n,m。[/align]
[align=left]下面m行,每行两个数x,y,表示一条边。[/align]
[align=left][/align]
[align=left]输出[/align]
[align=left]对第i组数据,输出[/align]
[align=left]Case #i:[/align]
[align=left]然后输出一个长度为n的字符串,表示每个点的标号。[/align]
[align=left][/align]
[align=left]限制条件[/align]
[align=left]1<=T<=100[/align]
[align=left]1<=n<=1000[/align]
[align=left]1<=m<=10000[/align]
[align=left]1<=x, y<=n[/align]
[align=left]图中无重边无自环。[/align]
[align=left][/align]
[align=left]样例输入[/align]
[align=left]1[/align]
[align=left]4 5[/align]
[align=left]1 2[/align]
[align=left]1 3[/align]
[align=left]1 4[/align]
[align=left]2 3[/align]
[align=left]2 4[/align]
[align=left][/align]
[align=left]样例输出[/align]
[align=left]Case #1:[/align]
[align=left]0001[/align]

解题报告:

[align=left]建立0/1线性方程组,然后解方程就可以了。每个点对应一个等式。时间复杂度O(n^3)。[/align]

解题代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cassert>
#include <ctime>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <bitset>
#include <sstream>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef pair<int,int> PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define N 1010

int TT, NN;
int n, m, S
;
bitset<N> a
;

int main () {
scanf("%d", &NN);
for (TT = 1; TT <= NN; TT++) {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++)
a[i].reset();
for (int i = 0; i < m; i ++) {
int x, y;
scanf("%d%d", &x, &y);
--x; --y;
a[x].set(y); a[y].set(x);
}
for (int i = 0; i < n; i++)
if (a[i].count() & 1) {
a[i].set(i);
a[i].set(N-1);
}
int rk = 0;
for (int i = 0; i < n; i ++) {
for (int j = rk; j < n; j ++)
if (a[j][i]) {
swap(a[j], a[rk]);
break;
}
if (!a[rk][i]) continue;
for (int j = rk+1; j < n; j ++)
if (a[j][i]) a[j] ^= a[rk];
rk ++;
}
memset(S, 0, sizeof S);
for (int i = rk-1; i >= 0; i --) {
int w = 0;
while (!a[i][w]) w ++;
if (a[i][N-1]) {
S[w] = 1;
for (int j = i-1; j >= 0; j -- )
if (a[j][w]) {
a[j][w] = 0;
a[j].flip(N-1);
}
}
w --;
}
printf("Case #%d:\n", TT);
for (int i = 0; i < n; i ++) printf("%d", S[i]);
puts ("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: