@xiaoziyao
2020-11-23T18:02:32.000000Z
字数 1271
阅读 1065
解题报告
AT2389 [AGC016E] Poor Turkeys解题报告:
神仙题。
我们设()表示:如果要活着,那么以后一定要为“抵命”。
可以用一个倒推的dp来求出数组,具体地说:
设为必须死去来抵一命的集合。
然后,我们枚举点对(),首先判断是不是一定得死去,如果不是,那么很显然只有才能让和同时存活(一只火鸡不能同时给和抵命)。
#include<stdio.h>
#include<bitset>
using namespace std;
const int maxn=405,maxm=100005;
int n,m,ans;
int a[maxm],b[maxm],no[maxn];
bitset<maxn>keep[maxn];
int main(){
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d",&a[i],&b[i]);
for(int i=1;i<=n;i++){
keep[i][i]=1;
for(int j=m;j>=1;j--){
if(keep[i][a[j]]&&keep[i][b[j]]){
no[i]=1;
break;
}
if(keep[i][a[j]])
keep[i][b[j]]=1;
else if(keep[i][b[j]])
keep[i][a[j]]=1;
}
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(no[i]==0&&no[j]==0&&(keep[i]&keep[j]).count()==0)
ans++;
printf("%d\n",ans);
return 0;
}