前置芝士:
关于差分约束的建图方法(口胡)
1、
对于 x>=y+a
y->x 连a的边
跑最长路,可求最小值
2、
对于x<=y+a
y->x连a的边
最短路,可求最大值
对于此题,x+1=y拆成 x+1>=y和x+1<=y
x->y连1的边,y->x连-1的边,如果存在负环(floyd后dis[i][i]<0)则无解(无解->存在一个权值不为0的环->一定存在一个正环一个负环)
tarjan缩点,不同强连通分量之间互不影响。
对于一个强连通分量里的点,两两之间的最短路的最大值即答案。(设这个联通分量中最大数为x,最小数为y, x<=y+dis[x][y],存在路径=dis[x][y],边权均为{0,-1,1},故此时ans=x-y+1有最大值dis[x][y]+1)
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define Formylove return 0
13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
15 const int N=607,M=100007;
16 typedef long long LL;
17 typedef double db;
18 using namespace std;
19 int n,m1,m2;
20 int f[N][N];
21
22 template<typename T>void read(T &x) {
23 char ch=getchar(); x=0; T f=1;
24 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
25 if(ch=='-') f=-1,ch=getchar();
26 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
27 }
28
29 int ecnt,fir[N],nxt[M<<1],to[M<<1];
30 void add(int u,int v) {
31 nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
32 }
33
34 vector<int>vc[N];
35 int dfn[N],low[N],dfk,sta[N],top,bl[N],tot;
36 void tarjan(int x) {
37 dfn[x]=low[x]=++dfk;
38 sta[++top]=x;
39 for(int i=fir[x];i;i=nxt[i]) {
40 if(!dfn[to[i]]) {
41 tarjan(to[i]);
42 low[x]=min(low[x],low[to[i]]);
43 }
44 else if(!bl[to[i]]) low[x]=min(low[x],dfn[to[i]]);
45 }
46 if(dfn[x]==low[x]) {
47 bl[x]=++tot;
48 for(;;) {
49 int u=sta[top--];
50 vc[tot].push_back(u);
51 bl[u]=tot;
52 if(u==x) break;
53 }
54 }
55 }
56
57 //#define ANS
58 int main() {
59 #ifdef ANS
60 freopen("1.in","r",stdin);
61 //freopen("1.out","w",stdout);
62 #endif
63 read(n); read(m1); read(m2);
64 memset(f,127/3,sizeof(f));
65 For(i,1,n) f[i][i]=0;
66 For(i,1,m1) {
67 int x,y;
68 read(x); read(y);
69 add(x,y);
70 add(y,x);
71 f[x][y]=min(f[x][y],1);
72 f[y][x]=min(f[y][x],-1);
73 }
74 For(i,1,m2) {
75 int x,y;
76 read(x); read(y);
77 add(y,x);
78 f[y][x]=min(f[y][x],0);
79 }
80 For(k,1,n) For(i,1,n) For(j,1,n)
81 f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
82 For(i,1,n) if(f[i][i]<0) {
83 puts("NIE");
84 return 0;
85 }
86 For(i,1,n) if(!dfn[i]) tarjan(i);
87 int ans=0;
88 For(i,1,tot) {
89 int up=vc[i].size();
90 int mx=0;
91 For(j,0,up-1) For(k,0,up-1)
92 mx=max(mx,f[vc[i][j]][vc[i][k]]);
93 ans+=mx+1;
94 }
95 printf("%d
",ans);
96 Formylove;
97 }
98 /*
99 4 2 2
100 1 2
101 3 4
102 1 4
103 3 1
104 */