其他分享
首页 > 其他分享> > 交通灯

交通灯

作者:互联网

  

Problem Description

相信交通灯对于你来说并不陌生,交通灯分为红色和绿色两个阶段,这两个阶段互相更替,保障着道路的安全。

在杭州一共有n个路口,编号依次为1到n。这些路口之间连接着m条双向道路,每条道路连接着两个不同的路口,且任意两个路口之间最多连接着一条道路。每条道路中央都设置着一个交通灯。

为了保障道路的安全,对于任意两条道路,如果它们连接了同一个路口,那么它们不能同色。

你的朋友正乘着飞机从杭州的上空飞过,并拍了一张杭州的照片。在照片里,每条道路的交通灯的颜色都清晰可辨。

你并不知道你的朋友是在什么时候按下的快门,于是你想统计出有多少种可能的方案。每个方案可以用一个颜色序列col1,col2,…,colm(coli∈{′Red′,′Green′})来描述,表示每个交通灯的颜色。

Input

第一行包含一个正整数T(1≤T≤5000),表示测试数据的组数。

每组数据第一行包含两个正整数n,m(1≤n,m≤100000),表示路口和道路的数量。

接下来m行,每行包含两个正整数ui,vi(1≤ui,vi≤n,ui≠vi),表示一条连接ui路口和vi路口的道路,任意两个路口之间最多连接着一条道路。

输入数据保证所有数据中n和m的总和都不超过1000000。

Output

对于每组数据输出一行一个整数,即ans,即可能的方案数对1000000007=109+7取模的结果。

注意城市布局可能不能保障道路的安全,此时的答案应该为0。

Sample Input

2
3 3
1 2
2 3
3 1
4 2
1 2
3 4

Sample Output

0
4

比赛的时候拿到这题感觉是可以做的
一开始想到 最大匹配 但是好像不行
然后开并查集 要求求出联通块个数cnt 然后2的cnt次幂就是答案( 比赛的时候居然写成2*cnt了 不知道错到哪里去了QAQ )
题意还要求我们判环
如果是奇数环则不行 偶数环是可以的 如正方形和三角形
比赛的时候我在并查集里面加了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][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;
}
View Code

标签:cnt,int,路口,交通灯,vis,define
来源: https://www.cnblogs.com/bxd123/p/10658413.html