zoukankan      html  css  js  c++  java
  • 《陕西师范大学第九届ACM程序设计竞赛》

    A:其实并不是特别难的一个题,想的太复杂了。

    首先,我们把关系看成能够传递的,那么我们并查集统计连通块之后。

    可以发现,对于一个连通块,最优方案肯定只有1个人会没朋友。

    因为一直把和当前删的点有关系的人的人删进去,最后肯定就能删完全部点,并且保证只有第一个进去的人没朋友。

    因为要保证字典序最小,我们每次合并并查集的时候,都让大的以小的为父节点,那么最后这个集合的根,肯定就是这个集合里最小的点。

    那么我们先把根都扔到小顶堆里,然后在把和堆顶相邻的没删的元素放入,因为小顶堆,会自己保证最小字典序。

    // Author: levil
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 1e6+5;
    const int M = 1e4;
    const LL Mod = 998244353;
    #define rg register
    #define pi acos(-1)
    #define INF 1e9
    #define INM INT_MIN
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        /*const int BUF_SIZE = 8e7;
        inline char nc(){
            static char buf[BUF_SIZE],*p1 = buf,*p2 = buf;
            return p1==p2&&(p2=(p1=buf)+fread(buf,1,BUF_SIZE,stdin),p1==p2)?EOF:*p1++;
        }*///file close.
        inline int read(){  
            int x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
        void print(int x){
            if(x < 0){x = -x;putchar('-');}
            if(x > 9) print(x/10);
            putchar(x%10+'0');
        }
    }
    using namespace FASTIO;
    void FRE(){
    /*freopen("data1.in","r",stdin);
    freopen("date1.out","w",stdout);*/}
    
    vector<int> G[N];
    int fa[N],vis[N];
    int Find(int x)
    {
        return x == fa[x] ? x : fa[x] = Find(fa[x]);
    }
    int main()
    {
        int ca;ca = read();
        while(ca--)
        {
            int n,m;n = read(),m = read();
            for(rg int i = 1;i <= n;++i) G[i].clear(),fa[i] = i,vis[i] = 0;
            while(m--)
            {
                int u,v;u = read(),v = read();
                G[u].push_back(v);
                G[v].push_back(u);
                int xx = Find(u),yy = Find(v);
                if(xx > yy) fa[xx] = yy;
                else fa[yy] = xx;
            }
            priority_queue<int,vector<int>,greater<int> > Q;
            int cnt = 0;
            for(rg int i = 1;i <= n;++i) if(fa[i] == i) Q.push(i),vis[i] = 1,cnt++;
            vector<int> ans;
            while(!Q.empty())
            {
                int u = Q.top();
                Q.pop();
                ans.push_back(u);
                for(auto v : G[u])
                {
                    if(!vis[v]) vis[v] = 1,Q.push(v); 
                }
            }
            printf("%d\n",cnt);
            for(int i = 0;i < ans.size();++i) printf("%d%c",ans[i],i == ans.size()-1 ? '\n' : ' ');
        }
        system("pause");     
        return 0;
    }
    View Code

    C:考虑m个点里选择n-1个不同的点,然后除了最大的值外,其他值都能出现两次,那么有出现两次的点有(n-2)种。

    那么重复出现的点在左右两边交换的时候,还是不改变。对于出现一次的点(除了最大值),它在最大值左右两边都是不同的方案。

    那么ans = C(m,n-1) * (n-2) * 2^(n-3)

    // Author: levil
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 2e5+5;
    const int M = 1e4;
    const LL Mod = 998244353;
    #define rg register
    #define pi acos(-1)
    #define INF 1e9
    #define INM INT_MIN
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        /*const int BUF_SIZE = 8e7;
        inline char nc(){
            static char buf[BUF_SIZE],*p1 = buf,*p2 = buf;
            return p1==p2&&(p2=(p1=buf)+fread(buf,1,BUF_SIZE,stdin),p1==p2)?EOF:*p1++;
        }*///file close.
        inline int read(){  
            int x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
        void print(int x){
            if(x < 0){x = -x;putchar('-');}
            if(x > 9) print(x/10);
            putchar(x%10+'0');
        }
    }
    using namespace FASTIO;
    void FRE(){
    /*freopen("data1.in","r",stdin);
    freopen("date1.out","w",stdout);*/}
    
    LL f[N];
    void init()
    {
        f[0] = 1;for(rg int i = 1;i < N;++i) f[i] = f[i-1]*i%Mod;
    }
    LL quick_mi(LL a,LL b)
    {
        LL re = 1;
        while(b)
        {
            if(b&1) re = re*a%Mod;
            a = a*a%Mod;
            b >>= 1;
        }
        return re;
    }
    LL inv(LL n){return quick_mi(n,Mod-2);}
    LL C(LL n,LL m){return f[n]*inv(f[m])%Mod*inv(f[n-m])%Mod;}
    int main()
    {
        init();
        int n,m;n = read(),m = read();
        if(n <= 2) printf("0\n");
        else{
            LL ma = C(m,n-1);//m个数里选n-1个不一样的。
            LL ans = ma*(n-2)%Mod*quick_mi(2,n-3)%Mod;
            printf("%lld\n",ans);
        }
       // system("pause");     
        return 0;
    }
    View Code
  • 相关阅读:
    2017.9.15 HTML学习总结---表格table
    2017.9.14 HTML学习总结---超链接标签图片标签
    2017.9.13 微机原理学习总结(一)
    2017.9.12 初入HTML -----学习总结(二)
    2017.9.11 初入HTML学习
    【死磕Java并发】-----Java内存模型之happens-before
    Java并发编程:volatile关键字解析[volatile最好的文章]
    【框架】[MyBatis]DAO层只写接口,不用写实现类
    MyBatis结果集处理,中resultType和resultMap的区别
    浅谈 Mybatis中的 ${ } 和 #{ }的区别
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/13517160.html
Copyright © 2011-2022 走看看