UESTC 1511(差分约束)

题目链接:http://acm.uestc.edu.cn/problem.php?pid=1511

思路:我们可以等到这样的5个关系式:

k=1:dsit[a]-dist[b]>=0&&dist[b]-dist[a]>=0

k=2:dist[a]-dist[b]<=-1;

k=3:dist[a]-dist[b]>=0;

k=4:dist[a]-dist[b]>=1;

k=5:dist[a]-dist[b]<=0;

然后就是spfa求最长路了。

 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 #include<queue>

 6 using namespace std;

 7 #define MAXN 100200

 8 #define inf 1<<30

 9 

10 struct Edge{

11     int v,w;

12     Edge(int vv,int ww):v(vv),w(ww){}

13 };

14 

15 int n,m,NE;

16 

17 int head[MAXN];

18 vector<vector<Edge> >g;

19 

20 void Insert(int u,int v,int w)

21 {

22     g[u].push_back(Edge(v,w));

23 }

24 

25 int dist[MAXN];

26 bool mark[MAXN];

27 int _count[MAXN];

28 

29 long long spfa(int vs)

30 {

31     memset(mark,false,(n+2)*sizeof(bool));

32     memset(_count,0,(n+2)*sizeof(int));

33     fill(dist,dist+n+4,-inf);

34     dist[vs]=0;

35     queue<int>que;

36     que.push(vs);

37     while(!que.empty()){

38         int u=que.front();

39         que.pop();

40         mark[u]=false;

41         _count[u]++;

42         if(_count[u]>n)return -1;

43         for(int i=0;i<g[u].size();i++){

44             int v=g[u][i].v,w=g[u][i].w;

45             if(dist[u]+w>dist[v]){

46                 dist[v]=dist[u]+w;

47                 if(!mark[v]){

48                     mark[v]=true;

49                     que.push(v);

50                 }

51             }

52         }

53     }

54     long long ans=0;

55     for(int i=1;i<=n;i++){

56         ans+=dist[i];

57     }

58     return ans;

59 }

60 

61 int main()

62 {

63     int k,u,v,flag;

64     while(~scanf("%d%d",&n,&m)){

65         NE=0;

66         memset(head,-1,(n+2)*sizeof(int));

67         flag=0;

68         g.clear();

69         g.resize(n+2);

70         while(m--){

71             scanf("%d%d%d",&k,&u,&v);

72             if(k==1){

73                 Insert(u,v,0);

74                 Insert(v,u,0);

75             }else if(k==2){

76                 Insert(u,v,1);

77                 if(u==v)flag=1;

78             }else if(k==3){

79                 Insert(v,u,0);

80             }else if(k==4){

81                 Insert(v,u,1);

82                 if(u==v)flag=1;

83             }else if(k==5){

84                 Insert(u,v,0);

85             }

86         }

87         for(int i=1;i<=n;i++){

88             Insert(0,i,1);

89         }

90         if(flag){

91             puts("-1");

92             continue;

93         }

94         printf("%lld\n",spfa(0));

95     }

96     return 0;

97 }
View Code

 

你可能感兴趣的:(差分约束)