@xiaoziyao
2020-11-23T10:02:32.000000Z
字数 1271
阅读 1540
解题报告
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;}
