zoukankan      html  css  js  c++  java
  • [HDU5765]Bonds

    题面

    题意

    给出一张(n)(m)边无向连通图,求每条边出现在多少个割集中。
    (nle20,mlefrac{n(n-1)}{2})

    sol

    所谓割集,就是指把(n)个点分成两个集合后,两个集合分别都是连通的。
    所以我们可以预处理出每一个点集是否连通。
    考虑边((u,v))。实际上((u,v))要出现在割集中,(u,v)就必然在不同的点集中。
    来一波总方案减不合法
    所有可行的割的方案减去(u,v)在同一个割集里面的方案。
    (u,v)在同一个割集里面的方案实际上就是集合({u,v})的超集之和。高维前缀和搞一搞。

    前面那个预处理每个点集是否连通,使用(bfs)处理。
    处理出每个点集的相邻点集,每次(bfs)时候向外扩展一个节点,若未访问就丢到队列里面去。
    复杂度(O(nlog{n}))

    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define ll long long
    int gi()
    {
        int x=0,w=1;char ch=getchar();
        while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
        if (ch=='-') w=0,ch=getchar();
        while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return w?x:-x;
    }
    const int N = 1<<21;
    int T,n,m,all,u[500],v[500],reach[N],able[N],sum,tot[N];
    queue<int>Q;
    inline int lowbit(int k){return k&-k;}
    int main()
    {
    	T=gi();
    	for (int zsy=1;zsy<=T;++zsy)
    	{
    		n=gi();m=gi();all=(1<<n)-1;sum=0;
    		memset(reach,0,sizeof(reach));
    		memset(able,0,sizeof(able));
    		memset(tot,0,sizeof(tot));
    		for (int i=1;i<=m;++i)
    		{
    			u[i]=gi();v[i]=gi();
    			reach[1<<u[i]]|=1<<v[i];
    			reach[1<<v[i]]|=1<<u[i];
    		}
    		for (int i=0;i<=all;++i)
    			reach[i]=reach[lowbit(i)]|reach[i^lowbit(i)];
    		for (int i=0;i<n;++i)
    			Q.push(1<<i),able[1<<i]=1;
    		while (!Q.empty())
    		{
    			int u=Q.front();Q.pop();
    			int tmp=reach[u];
    			while (tmp)
    			{
    				int v=u|lowbit(tmp);
    				if (!able[v]) able[v]=1,Q.push(v);
    				tmp^=lowbit(tmp);
    			}
    		}
    		for (int i=0;i<=all;++i)
    			if (able[i]&&able[i^all])
    				++sum,++tot[i];
    		sum>>=1;
    		for (int j=0;j<n;++j)
    			for (int i=all;i>=0;--i)
    				if ((i&(1<<j))==0) tot[i]+=tot[i|(1<<j)];
    		printf("Case #%d:",zsy);
    		for (int i=1;i<=m;++i)
    			printf(" %d",sum-tot[(1<<u[i])|(1<<v[i])]);
    		puts("");
    	}
    }
    
  • 相关阅读:
    使用discourse 作为社区工具
    dremio schema 更新的问题
    go-mysql-server 新版本发布
    开发一个dremio user_agent 解析函数
    java 几个不错的user_agent 解析工具包
    Docker Swarm 高可用详解
    用Docker Swarm实现容器服务高可用
    Docker 1.12 :认识 Swarm 模式下的节点崩溃处理
    Linux下磁盘分区调整(在不使用LVM的情况下)
    docker-swarm----多机容器管理
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8460378.html
Copyright © 2011-2022 走看看