1. 程式人生 > 實用技巧 >E - Capitalism(求差值最大。”=“情況的差分約束)

E - Capitalism(求差值最大。”=“情況的差分約束)

題:https://codeforces.com/contest/1450/problem/E

題意:給定n點m邊圖,邊:[u,v,d]當d為1時,a[v]-a[u]=1,當d為0時,|a[v]-a[u]|=0,求給a陣列賦值,圖關係合法且最大化max{ a[i] } - min{ a[i] }

分析:

  1. 差分約束”=“的情況,將d==1時的情況轉化為a[v]-a[u]<=1, a[v]-a[u]>=1,所以cost[u][v]=1,cost[v][u]=-1。
  2. 同理,d==0時cost[u][v]=1,cost[v][u]=1, 求差值最大根據差分約束去跑最短路;
  3. ”NO“情況就判斷有無負權環和判斷路徑是否合法,
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define MP make_pair
#define UM unordered_map
typedef long long ll;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const ll INF=1e18;
#define pi 3.1415926535898
#define DEC (pi/180)
const int M=202;
int cost[M][M];
int u[M*10],v[M*10
],d[M*10]; void py(){ puts("YES"); } void pn(){ puts("NO"); } int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j) cost[i][j]=inf; for(int i=1;i<=m;i++){ scanf("%d%d%d",&u[i],&v[i],&d[i]); cost[u[i]][v[i]]
=1; cost[v[i]][u[i]]=(d[i] == 1 ? -1 : 1); } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cost[i][j]=min(cost[i][j],cost[i][k]+cost[k][j]); } } ///negative for(int i=1;i<=n;i++) if(cost[i][i]<0) return pn(),0; ///find max int pos=1,maxx=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(maxx<cost[i][j]){ maxx=cost[i][j]; pos=i; } ///judge legal for(int i=1;i<=m;i++) if(cost[pos][u[i]]==cost[pos][v[i]]) return pn(),0; py(); printf("%d\n",maxx); for(int i=1;i<=n;i++) printf("%d ",cost[pos][i]); return 0; }
View Code