zoukankan      html  css  js  c++  java
  • AtCoder Grand Contest 016 E

    题目传送门:https://agc016.contest.atcoder.jp/tasks/agc016_e

    题目大意:

    (N)只火鸡,现有(M)个人,每个人指定了两只火鸡(x,y),每人依次进行操作,会从(x,y)中选一只火鸡吃掉;如果只有一个,那么必定吃掉剩下那个;如果都没有,这个人只能饿着肚子离开了……

    问最后有多少对火鸡可能存活


    我们设状态(f_{i,j})表示如果要留下(i),那么是否要炖了(j),初始状态(f_{i,i}=1)

    我们倒序考虑,如果(f_{i,j}=1),那么必然存在某个时刻会在(i,j)中抉择,这时(j)就会为了(i)挡枪子,但在这之前的时间,(j)需要收到和(i)一样的保护。那么这样就会牵扯到一堆火鸡,于是我们记(S_i)表示要留下(i),要为这一系列连锁反应挡枪的火鸡集合

    如果存在某个时刻,需要在(x,y)中选择,但是存在(f_{i,x}=f_{i,y}=1),那么(i)就无法存活,这是结论1

    考虑一对鸡((i,j))如何被留下,如果存在一只鸡(x),既要保护(i),也要保护(j),那么((i,j))必然不能共存,因为(x)只有一条命……因此我们可以得到,((i,j))同时存在,当且仅当(S_iland S_j=varnothing),这是结论2

    应用结论1和2即可,复杂度为(O(nm+n^3)),集合判交可以使用bitset优化

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline char gc(){
    	static char buf[1000000],*p1=buf,*p2=buf;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int frd(){
    	int x=0,f=1; char ch=gc();
    	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<3)+(x<<1)+ch-'0';
    	return x*f;
    }
    inline int read(){
    	int x=0,f=1; char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<3)+(x<<1)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x<0)	putchar('-'),x=-x;
    	if (x>9)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=4e2,M=1e5;
    int A[M+10],B[M+10];
    bool vis[N+10],sub[N+10][N+10];
    int main(){
    	int n=read(),m=read(),Ans=0;
    	for (int i=1;i<=m;i++)	A[i]=read(),B[i]=read();
    	for (int i=1;i<=n;i++){
    		sub[i][i]=1;
    		for (int j=m;j;j--){
    			bool x=sub[i][A[j]],y=sub[i][B[j]];
    			if (x&&y)	vis[i]=1;
    			else	if (x)	sub[i][B[j]]=1;
    			else	if (y)	sub[i][A[j]]=1;
    		}
    	}
    	for (int i=1;i<=n;i++){
    		if (vis[i])	continue;
    		for (int j=i+1;j<=n;j++){
    			if (vis[j])	continue;
    			bool flag=1;
    			for (int k=1;k<=n;k++)	if (sub[i][k]&&sub[j][k])	flag=0;
    			Ans+=flag;
    		}
    	}
    	printf("%d
    ",Ans);
    	return 0;
    }
    
  • 相关阅读:
    K8s--09 编写mysql的持久化deployment
    K8s--08 prometheus监控
    K8s--07 configMap资源
    K8s--06 K8s数据持久化
    k8S--05 K8s控制器类型
    k8s--04 部署harbor作为k8s镜像仓库
    K8s--03 资源类型
    K8s--02 K8S部署
    K8s--01 Kubernetes简介
    video2gift环境安装(Theano等)
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/10167671.html
Copyright © 2011-2022 走看看