记录编号 443889 评测结果 AAAAAAAAAA
题目名称 [SYOI 2015] Asm_Def三角形 最终得分 100
用户昵称 GravatarShirry 是否通过 通过
代码语言 C++ 运行时间 0.215 s
提交时间 2017-09-01 16:40:45 内存使用 3.36 MiB
显示代码纯文本
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
#include<vector>
#define mod 998244353
using namespace std;
const int maxn=100010;
int n,m,num,ans=0,flag=true,f[maxn],vis[maxn],color[maxn];
int c=0,u[maxn],v[maxn];//被加固的边
vector<int>s[maxn];
int Find(int x){
	if(f[x]==x)return x;
	return f[x]=Find(f[x]);
}
void Merge(int x,int y){
	int f1=Find(x),f2=Find(y);
	if(f1!=f2)num--,f[f1]=f2;
}
bool BFS(int x){
	queue<int>p;
	p.push(x),color[x]=1;
	while(!p.empty()){
		int q=p.front();
		p.pop();
		for(int i=0;i<(int)s[q].size();i++){
			int m=s[q][i];
			if(color[m]==-1)p.push(m),color[m]=!color[q];
			if(color[m]==color[q])return false;
		}
	}
	return true;
}
long long quickpow(long long x,long long y){
	long long ans=1;
	while(y){
		if(y%2)ans*=x;
		ans%=mod;
		x=(x*x)%mod;
		y/=2;
	}
	return ans;
}
int main(){
	freopen("tria.in","r",stdin);
	freopen("tria.out","w",stdout);
	scanf("%d%d",&n,&m);
	memset(color,-1,sizeof(color));
	for(int i=1;i<=n;i++)f[i]=i;
	int p,q,op;
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&op,&p,&q);
		if(op==1)c++,u[c]=p,v[c]=q;
		else Merge(p,q);
	}
	for(int i=1;i<=c;i++){
		p=u[i],q=v[i];
		int f1=Find(p),f2=Find(q);
		if(f1==f2){
			flag=0;
			break;
		}
		if(f1==1||f2==1)continue;
		s[f1].push_back(f2),s[f2].push_back(f1);
	}
	for(int i=1;i<=n;i++){
		int f1=Find(i);
		if(color[f1]==-1){
			int t=BFS(f1);
			if(t==0)flag=0;
		}
	}
	for(int i=1;i<=c;i++)Merge(u[i],v[i]);//进行第二次缩点
	memset(vis,0,sizeof(vis));
	num=0;
	for(int i=1;i<=n;i++){
		int f1=Find(i);
		if(!vis[f1])num++,vis[f1]=1;
	}
	num--;
	long long ans=quickpow(2,num);
	if(flag)printf("%lld\n",ans);
	else printf("0\n");
	return 0;
}