首页 > 其他 > 详细

#dp#nssl 1478 题

时间:2020-08-14 23:24:34      阅读:80      评论:0      收藏:0      [点我收藏+]

技术分享图片


分析

\(f[i]\)表示第\(i\)个是否幸存,\(dp[i][j]\)表示若第\(i\)个幸存,第\(j\)个是否必死
倒序枚举人,如果存在\(dp[i][a[x]],dp[i][b[x]]\)同时为是,为了避免矛盾,第\(i\)个必死
如果存在\(dp[i][a[x]],dp[i][b[x]]\)其中一个为是,那么另一个也为是
最后枚举两个点\(i,j\)若没有一个点\(k\)使得\(dp[i][k],dp[j][k]\)同时为是,那么\((i,j)\)幸存


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=411,M=50011;
int n,m,a[M],b[M],ans; bool f[N],dp[N][N];
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
signed main(){
	n=iut(),m=iut();
	for (rr int i=1;i<=m;++i) a[i]=iut(),b[i]=iut();
	for (rr int i=1;i<=n;++i){
		f[i]=dp[i][i]=1;
		for (rr int j=m;j>=1;--j){
			if (!dp[i][a[j]]&&!dp[i][b[j]]) continue;
			if (dp[i][a[j]]&&dp[i][b[j]]){f[i]=0; break;}
			dp[i][a[j]]=dp[i][b[j]]=1;
		}
	}
	for (rr int i=1;i<n;++i)
	for (rr int j=i+1;j<=n;++j)
	if (f[i]&&f[j]){
		rr int flag=1;
		for (rr int k=1;k<=n;++k)
		if (dp[i][k]&&dp[j][k]){
			flag=0; break;
		}
		if (flag) ++ans;
	}
	return !printf("%d",ans); 
}

#dp#nssl 1478 题

原文:https://www.cnblogs.com/Spare-No-Effort/p/13504615.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!