码迷,mamicode.com
首页 > 其他好文 > 详细

small test on 5.30 night T2

时间:2018-05-30 22:41:14      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:efi   std   ace   分享图片   表示   line   out   span   oid   

技术分享图片

 

(题面写错了,应该是一条从b -> a 的边)

 

    让我们设状态 (a,b,c) 表示存在一个点k,使得  dist(k,b) - dist(k,a) * 2 + 3 = c,显然这里的第三维可以压成0~2,因为每次a走出去一步,b就要多走出去两步,可以证明a和b交替走是不会影响最后的答案的,所以直接一遍BFS出所有状态,然后答案就是 形如(a,b,0) 的状态个数。

 

#include<iostream>
#include<cstdio>
#include<queue>
#define ll long long
using namespace std;
const int maxn=3005;
int n,m,hd[maxn],ne[maxn],to[maxn],num,ans,N[3]={1,2,0};
bool v[maxn][maxn][3];

struct node{ int a,b,c;};
queue<node> q;

inline void add(int x,int y){ to[++num]=y,ne[num]=hd[x],hd[x]=num;}

inline void solve(){
	for(int i=1;i<=n;i++) v[i][i][0]=1,q.push((node){i,i,0});
	
	node x;
	while(!q.empty()){
		x=q.front(),q.pop();
		
		if(x.c){
			for(int i=hd[x.b];i;i=ne[i]) if(!v[x.a][to[i]][N[x.c]]){
				v[x.a][to[i]][N[x.c]]=1;
				q.push((node){x.a,to[i],N[x.c]});
			}
		}
		else{
			ans++;
			for(int i=hd[x.a];i;i=ne[i]) if(!v[to[i]][x.b][1]){
				v[to[i]][x.b][1]=1;
				q.push((node){to[i],x.b,1});
			}
		}
	}
}

int main(){
//	freopen("dierti.in","r",stdin);
//	freopen("dierti.out","w",stdout);
	
	scanf("%d%d",&n,&m);
    int uu,vv;
	for(int i=1;i<=m;i++) scanf("%d%d",&uu,&vv),add(vv,uu);
	
	solve();
	
	printf("%d\n",ans);
	return 0;
}

  

  

small test on 5.30 night T2

标签:efi   std   ace   分享图片   表示   line   out   span   oid   

原文地址:https://www.cnblogs.com/JYYHH/p/9113708.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!