• 【UNR #2】UOJ拯救计划


    UOJ小清新题表

    题目内容

    UOJ链接

    题面太长了(其实是我懒得改LaTeX了)
    一句话题意:
    给出 (n) 个点和 (m) 条边,对其进行染色,共 (k) 种颜色,要求同一条边两点颜色不同,输出方案数(pmod 6)

    数据范围

    (1leq nleq 10^5,0leq mleq 2 imes 10^5,1leq kleq 10^4)

    思路

    水题解,他不香吗

    由于本人并不会UOJ中的其他题,所以来水最简单的一道了

    直接计算的话,答案为:

    [sumlimits^k_{i=1}A^i_k imes x ]

    其中(x)为用(i)种颜色的方案数,不过你可能惊喜的发现这个是个(NPC)问题。

    所以为什么我要在一句话题意中把( ext{mod} 6)写上呢,因为当(igeq 3)的时候,答案肯定为0。

    所以好像只需要讨论(i=1,2)即可。

    • (i=1)
      • (m=0),直接是一堆点,(ans=1)
      • (m ot=0),那么只能(ans=0)
    • (i=2)
      • (m=0),对于(n)个点都有(2)种颜色可选,(ans=k^2)
      • (m ot=0),设图中共有(tot)个联通块,(ans=C^2_k imes 2^{tot})。当然如果发现有一个联通块无法完成染色,答案就直接是(0)

    然后其实(m=0)的时候直接答案就是(k^n)就行。

    代码

    #include <bits/stdc++.h>
    #define int long long
    #define Clean(a) memset(a,0,sizeof(a))
    using namespace std;
    const int maxn=5e5+10;
    const int Mod=6;
    int n,m,k;
    int vis[maxn];
    
    struct Edge{
        int from,to,w,nxt;
    }e[maxn<<1];
    
    inline int read(){
        int x=0,fopt=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')fopt=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            x=(x<<3)+(x<<1)+ch-48;
            ch=getchar();
        }
        return x*fopt;
    }
    
    int head[maxn],cnt;
    inline void add(int u,int v){
        e[++cnt].from=u;
        e[cnt].to=v;
        e[cnt].nxt=head[u];
        head[u]=cnt;
    }
    
    inline int qpow(int x,int b){
        int ans=1,base=x;
        while(b){
            if(b&1)ans=ans*base%Mod;
            base=base*base%Mod;
            b>>=1;
        }
        return ans;
    }
    
    bool dfs(int u,int col){
        vis[u]=col;
        for(int i=head[u];i;i=e[i].nxt){
            int v=e[i].to;
            if(!vis[v]){
                if(!dfs(v,-col))return 0;
            }else if(vis[u]==vis[v])return 0;
            
        }
        return 1;
    }
    
    inline void Init(){
        cnt=0;
        Clean(e);
        Clean(head);
        Clean(vis);
    }
    
    signed main(){
        int T=read();
        while(T--){
            n=read();m=read();k=read();
            if(m==0){
                printf("%lld
    ",qpow(k,n));
                continue;
            }else{
                if(k==1){
                    for(int i=1;i<=m;i++){
                        read();read();
                    }
                    puts("0");
                    continue;
                }else{
                    Init();
                    for(int i=1;i<=m;i++){
                        int u=read(),v=read();
                        add(u,v);add(v,u);
                    }
                    int tot=0,flag=1;
                    for(int i=1;i<=n;i++){
                        if(!vis[i]){
                            if(dfs(i,1))tot++;
                            else{
                                flag=0;break;
                            }
                        }
                    }
                    printf("%lld
    ",(k*(k-1)/2)%Mod*qpow(2,tot)*flag%Mod);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    linux查看公网ip的方法
    统计文件或文件夹个数
    python manage.py shell
    炒冷饭,对于数据库“删除”操作大家平时都是物理删除,还是逻辑删除啊?
    SQL表名,应该用表对应资源对象的复数形式还是单数形式
    git常用命令
    Django ORM中的模糊查询
    threading 学习笔记
    class类笔记整理
    函数笔记整理
  • 原文地址:https://www.cnblogs.com/Midoria7/p/13507397.html
Copyright © 2020-2023  润新知