标签:不同 rip iii 交通灯 open using while opened 情况
2 3 3 1 2 2 3 3 1 4 2 1 2 3 4
0 4
比赛的时候拿到这题感觉是可以做的
一开始想到 最大匹配 但是好像不行
然后开并查集 要求求出联通块个数cnt 然后2的cnt次幂就是答案( 比赛的时候居然写成2*cnt了 不知道错到哪里去了QAQ )
题意还要求我们判环
如果是奇数环则不行 偶数环是可以的 如正方形和三角形
比赛的时候我在并查集里面加了cnt 以此来判环
这种想法是对的 因为一个点如果有三条边显然是错的 除去这种情况 剩下的就是一个点小于等于两条边 那么只能构成一条链或者一个环 比赛的时候几乎写出来了 但是最后答案的形式弄错饿了(2*cnt)
其实很多情况不需要什么算法 直接乱搞就行了
补题的时候很快就想到思路 用一个vis就可以表示两种灯的状态了
过程中还是wa了一些细节
1.爆int了 开ll 并且只要是乘法 只管加mod就行了!!!
2.如果是0个联通块 不应该是2的0次方 而是0
一定要等思路完善了再开始敲 不然只是浪费时间 并且只想沿着错误的思路思考 难以放弃并且重新开启新的思路
比赛的思路:
#include<bits/stdc++.h> using namespace std; //input #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);i--) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m); #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define inf 0x3f3f3f3f #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define N 500+5 #define mod 1000000007 int vis[100005]; int cnt[100005]; int f[100005]; int find1(int x) { return x==f[x]?x:f[x]=find1(f[x]); } void union1(int a,int b) { int x=find1(a); int y=find1(b); if(x!=y) f[x]=y,cnt[y]+=cnt[x]; } ll fastpow(ll x,int n) { ll ans=1; while(n) { if(n&1) ans*=x,ans%=mod; x*=x,x%=mod;//疯狂加mod就完事了 n>>=1; } return ans%mod; } int main() { int cas; RI(cas); while(cas--) { int n,m;RII(n,m); rep(i,1,n) f[i]=i,vis[i]=0,cnt[i]=1; int ok=1; while(m--) { int a,b;RII(a,b); if(!ok)continue; vis[a]++; vis[b]++; if(vis[a]>2||vis[b]>2)ok=0; int x=find1(a),y=find1(b); if(x!=y) union1(a,b); else { if(cnt[x]%2==1)ok=0;//如果为奇数环 则无法实现 else union1(a,b); } } if(!ok)printf("0\n"); else { ll cnt=0; rep(i,1,n) if(f[i]==i&&vis[i]) cnt++; if(cnt==0)printf("0\n"); else printf("%lld\n",fastpow(2,cnt)); } } return 0; }
模拟输入路径写法:
#include<bits/stdc++.h> using namespace std; //input #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);i--) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m); #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define inf 0x3f3f3f3f #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define N 500+5 #define mod 1000000007 int vis[100005][2]; int f[100005]; int find1(int x) { return x==f[x]?x:f[x]=find1(f[x]); } ll fastpow(ll x,int n) { ll ans=1; while(n) { if(n&1) ans*=x,ans%=mod; x*=x,x%=mod;//疯狂加mod就完事了 n>>=1; } return ans%mod; } int main() { int cas; RI(cas); while(cas--) { int n,m; RII(n,m); rep(i,1,n)f[i]=i,vis[i][0]=vis[i][1]=0; int ok=1; while(m--) { int a,b; RII(a,b); if(!ok)continue; if(!vis[a][0]&&!vis[b][0]) vis[a][0]=vis[b][0]=1,f[ find1(a) ]=find1(b); else if(!vis[a][1]&&!vis[b][1]) vis[a][1]=vis[b][1]=1,f[ find1(a) ]=find1(b); else ok=0; } if(!ok)printf("0\n"); else { ll cnt=0; rep(i,1,n) if(f[i]==i&&( vis[i][0]||vis[i][1]) )//如果是孤立的点而不是路则不能给路染色 cnt++; if(cnt==0) printf("0\n"); else printf("%lld\n",fastpow( 2,cnt )); } } return 0; }
标签:不同 rip iii 交通灯 open using while opened 情况
原文地址:https://www.cnblogs.com/bxd123/p/10658413.html