Dfs type SPFA + || negative answer half ring || BZOJ 4773

answer:

The basic idea is half the answer, each with Dfs type SPFA verify that the answer is legitimate.

My little details in the comments in the code.

Code:

 

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 inline int rd(){
 5     int x=0,f=1; char c=getchar();
 6     while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
 7     while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
 8     return f*x;
 9 }
10 const int maxn=305,maxm=305*305,inf=(1<<30)-5;
11 int N,M,edge_head[maxn],num_edge=0,u,v,w,Dis[maxn];
12 bool vis[maxn],flag;
13 struct Edge{ int to,nx,dis; }edge[maxm];
14 inline voidAdd_edge ( int  from , int to, int DIS) {
 15      Edge [num_edge ++] = .nx edge_head [ from ];
 16      Edge [num_edge] .to = to;
 . 17      Edge [num_edge] = .dis DIS;
 18 is      edge_head [ from ] = num_edge;
 . 19      return ;
 20 is  }
 21 is inline void the SPFA ( int x, int now, int Limit) {
 22 is  // determines whether there is currently located x, now with the now points, points not exceeding negative Limit ring 
23      IF (Flag)return;
24     for(int i=edge_head[x];i;i=edge[i].nx){
25         int y=edge[i].to;
26         if(Dis[y]>=Dis[x]+edge[i].dis){
27             if(vis[y]){
28                 flag=1;
29                 return;
30             } 
31             else if(now+1<=Limit){
32                 vis[y]=1;
33                 Dis[y]=Dis[x]+edge[i].dis;
34                 The SPFA (Y, now + . 1 , Limit);
 35                  VIS [Y] = 0 ;
 36                  // here Dis [y] do backtracking, is actually a prune 
37 [              }
 38 is          }
 39      }
 40      return ;
 41 is  }
 42 is  int main () {
 43 is      N = RD (); M = RD ();
 44 is      for ( int I = . 1 ; I <= M; I ++ ) {
 45          U = RD (); V = RD (); W = RD () ;
 46 is          add_edge (U, V, W);
 47      }
 48      
49     flag=0;
50     for(int i=1;i<=N;i++){    
51         memset(vis,0,sizeof(vis));
52         memset(Dis,0,sizeof(Dis));
53         vis[i]=1;
54         SPFA(i,1,N);
55         if(flag) break;
56     }
57     if(flag==0){
58         printf("0\n");
59         return 0;
60     }
61     
62     int l=2,r=N;
63     while(l<=r){
64         int mid=(l+r)>>1;
65         flag=0;
66         for(int i=1;i<=N;i++){                
67             memset(vis,0,sizeof(vis));
68             memset(Dis,0,sizeof(Dis));
69             vis[i]=1;
70             SPFA(i,1,mid);
71             if(flag){
72                 r=mid-1;
73                 break;
74             }
75         }
76         if(!flag) l=mid+1;
77     }
78     printf("%d\n",l);
79     return 0;
80 }
View Code

 


By:AlenaNuna

 

Guess you like

Origin www.cnblogs.com/AlenaNuna/p/11695080.html