CF1450E
差分约束板子。
因为相邻差绝对值为 $1$ ,所以有奇环一定无解。
$a_i+1=a_j$ 很好处理,关键在于 $|a_i-a_j|=1$ 。
对于 $|a_i-a_j|=1$ ,拆成两个条件: $a_i \leq a_j+1$和$a_i \geq a_j-1$ 。
枚举起点,特判有连边的点的最短路相等即可。
为什么呢?因为 $d_i=d_j$ 意味着起点到 $i$ 与 $j$ 距离相等, $i$ ,起点, $j$ 形成长度为偶数的路径,又因为 $i$ , $j$ 有边,所以存在奇环。
这题评2700原因应该是外国人不知道差分约束。
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,g[200][200]; int a[2000],b[2000],c; int main(void) { memset(g,0x3f,sizeof(g)); scanf("%d%d",&n,&m); for(int i=0;i<m;i++){ scanf("%d%d%d",&a[i],&b[i],&c); g[a[i]-1][b[i]-1]=1; if(c==1) g[b[i]-1][a[i]-1]=-1; else g[b[i]-1][a[i]-1]=1; } for(int i=0;i<n;i++) g[i][i]=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) g[j][k]=min(g[j][k],g[j][i]+g[i][k]); int pos=-1,ans=-1; for(int i=0;i<n;i++){ if(g[i][i]<0){ printf("NO\n"); return 0; } int mx=-n,mn=n; for(int j=0;j<n;j++){ mx=max(mx,g[i][j]); mn=min(mn,g[i][j]); } for(int j=0;j<m;j++) if(g[i][a[j]-1]==g[i][b[j]-1]) mx=-n; if(ans<mx-mn){ ans=mx-mn; pos=i; } } if(ans==-1) printf("NO\n"); else{ printf("YES\n%d\n",ans); for(int i=0;i<n;i++) printf("%d%c",g[pos][i]+n,i==n-1?'\n':' '); } return 0; } /* */

浙公网安备 33010602011771号