small test on 5.30 night T2
阿新 • • 發佈:2018-05-31
一個 ima 直接 CP line %d clas 圖片 int
(題面寫錯了,應該是一條從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