FIG smallest ring (the Floyd algorithm)

topic:

  Given a directed graph, find its smallest ring.

  There should contain at least two vertices of the directed acyclic graph, without having at least three vertices to a ring of FIG.

Brief:

  If you are familiar with the principles of floyd algorithm, then we will know each cycle is to the distance between the point and the point of relaxation by the outermost k, then relaxation for the current dis [i] [j] has not joined k, If there is dis [i] [j] + map [i] [k] + map [k] [j] <mincircle, then the time i and j and k, the path will form a smallest ring, followed by addition of 'k' relaxation, find the next point can be obtained through other relaxation smallest ring, pay attention to the smallest ring when seeking to update each one will find a path, can not wait until the last to seek ,, because the last pre array is not consistent with the current .

Undirected graph Code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<vector>
 5 #include<queue>
 6 #include<cstring>
 7 #include<algorithm>
 8 #define numm ch-48
 9 #define pd putchar(' ')
10 #define pn putchar('\n')
11 #define pb push_back
12 #define debug(args...) cout<<#args<<"->"<<args<<endl
13 #define bug cout<<"************"
14 using namespace std;
15 template <typename T>
16 void read(T &res) {
17     bool flag=false;char ch;
18     while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
19     for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
20     flag&&(res=-res);
21 }
22 template <typename T>
23 void write(T x) {
24     if(x<0) putchar('-'),x=-x;
25     if(x>9) write(x/10);
26     putchar(x%10+'0');
27 }
28 typedef long long ll;
29 const int maxn=110+10;
30 const int maxm=50010;
31 const int inf=0x3f3f3f3f;
32 const int mod=1e9+7;
33 int a[maxn][maxn],dis[maxn][maxn],pre[maxn][maxn];
34 vector<int>ans;
35 bool floyed(int n) {    ///判最小环
36     int mircle=inf;
37     bool flag=false;
38     for(int k=1;k<=n;k++) {
39         for(int i=1;i<k;i++)
40             for(int j=i+1;j<k;j++) {    /// If the ring needs to include at least three points, the I! = J! = K 
41 is                  IF (DIS [I] [J]! = INF && A [I] [K]! = INF && A [K] [J]! = INF) { /// find a, then updated 
42 is                      IF (mircle> DIS [I] [J] + a [I] [K] + a [K] [J]) {
 43 is                          mircle DIS = [I] [ J] + A [I] [K] + A [K] [J];
 44 is                          In Flag = to true ;
 45                          ans.clear ();
 46 is                          ans.push_back (K);
 47                          ans.push_back (J);
 48                          int D = J;
 49                          do {
 50                              D = pre [I] [D];
51 is                              ans.push_back (D);
 52 is                          } the while (! D = I);
 53 is                      }
 54 is                  }
 55              }
 56 is          for ( int I = . 1 ; I <= n-; I ++) { /// If the ring contains at least three required point, I = J = K!! 
57 is              IF (I =! K)
 58                  for ( int J = . 1 ; J <= n-; J ++ ) {
 59                      IF ! (I = J && J = K && DIS [I] [K]! ! && DIS INF = [K] [J]! = INF) {
 60                          IF (DIS [I] [J]> DIS [I] [K] +dis[k][j]) {
61                             dis[i][j]=dis[i][k]+dis[k][j];
62                             pre[i][j]=pre[k][j];    ///attention!!!
63                         }
64                     }
65                 }
66         }
67     }
68     return flag;
69 }
70 int main()
71 {
72     int m,n;
73     read(n),read(m);
74     memset(a,inf,sizeof(a));
75     memset(dis,inf,sizeof(dis));
76     for(int i=1;i<=n;i++) {
77         for(int j=1;j<=n;j++)
78             pre[i][j]=i;
79     }
80     for(int i=1;i<=m;i++) {
81         int u,v,w;
82         read(u),read(v),read(w);
83         a[u][v]=a[v][u]=dis[u][v]=dis[v][u]=w;
84     }
85     if(floyed(n)) {
86         for(int i=0;i<ans.size();i++)
87             write(ans[i]),pd;
88         pn;
89     }
90     else puts("No solution.");
91     return 0;
92 }
View Code

Digraph Code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<vector>
 5 #include<queue>
 6 #include<cstring>
 7 #include<algorithm>
 8 #define numm ch-48
 9 #define pd putchar(' ')
10 #define pn putchar('\n')
11 #define pb push_back
12 #define debug(args...) cout<<#args<<"->"<<args<<endl
13 #define bug cout<<"************"
14 using namespace std;
15 template <typename T>
16 void read(T &res) {
17     bool flag=false;char ch;
18     while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
19     for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
20     flag&&(res=-res);
21 }
22 template <typename T>
23 void write(T x) {
24     if(x<0) putchar('-'),x=-x;
25     if(x>9) write(x/10);
26     putchar(x%10+'0');
27 }
28 typedef long long ll;
29 const int maxn=2010+10;
30 const int maxm=50010;
31 const int inf=0x3f3f3f3f;
32 const int mod=1e9+7;
33 int a[maxn][maxn],dis[maxn][maxn],pre[maxn][maxn];
34 int que[maxn+100],cnt;
35 bool floyed(int n) {    ///有向图判最小环
36     int mincircle=inf;
37     bool flag=false;
38     for(int k=1;k<=n;k++) {
39         for(int i=1;i<=n;i++) {
40             if(a[k][i]==inf||a[k][i]>mincircle) continue;
41             for(int j=1;j<=n;j++) {
42                 if(i==k&&j==k) continue;
43                 if(dis[i][j]!=inf&&a[j][k]!=inf) {
44                     if(mincircle>dis[i][j]+a[j][k]+a[k][i]) {
45                         mincircle=dis[i][j]+a[j][k]+a[k][i];
46                         flag=true;
47                         cnt=0;
48                         que[++cnt]=k;
49                         que[++cnt]=j;
50                         int d=j;
51                         do {
52                             d=pre[i][d];
53                             if(d!=j&&d!=k)
54                                 que[++cnt]=d;
55                         }while(d!=i);
56 
57                     }
58                 }
59             }
60         }
61         for(int i=1;i<=n;i++) {
62             if(dis[i][k]==inf) continue;
63             for(int j=1;j<=n;j++) {
64                 if(i==k&&j==k) continue;
65                 if(dis[k][j]!=inf) {
66                     if(dis[i][j]>dis[i][k]+dis[k][j]) {
67                         dis[i][j]=dis[i][k]+dis[k][j];
68                         pre[i][j]=pre[k][j];
69                     }
70                 }
71             }
72         }
73     }
74     return flag;
75 }
76 int main()
77 {
78     int m,n;
79     read(n),read(m);
80     memset(a,inf,sizeof(a));
81     memset(dis,inf,sizeof(dis));
82     for(int i=1;i<=n;i++) {
83         a[i][i]=dis[i][i]=0;
84         for(int j=1;j<=n;j++)
85             pre[i][j]=i;
86     }
87     for(int i=1;i<=m;i++) {
88         int u,v,w;
89         read(u),read(v),read(w);
90         a[u][v]=dis[u][v]=min(w,a[u][v]);
91     }
92     if(floyed(n)) {
93         for(int i=cnt;i;i--)
94             write(que[i]),pd;
95         pn;
96     }
97     else puts("No solution.");
98     return 0;
99 }
View Code

 

 

 

Guess you like

Origin www.cnblogs.com/wuliking/p/11584309.html