dijkstra求最小环
任意一个环的权值,我们都可以看成两个有边相连的结点i、j的直接距离加上i、j间不包含边(边i->j)的最短路径。
求最短路径我们第一个想到的就是Dijkstra算法。
而Dijkstra所求的是一个点到所有点的最短距离。
用Dijkstra所求的i、j的最短距离一定是i、j的直接距离(如果i,j连通),所以我们需要先将i、j的边从图中删除(若i,j不连通,则不用删除),再用Dijkstra求新图中i、j的最短距离即可。
所以我们每次在图中选取一条边,把它从图中删掉.
然后对删掉的那条边所对应的2点进行Dijkstra,也就是m次Dijkstra。
时间复杂度:若为稀疏图,复杂度为O(n^3)
若为稠密图,复杂度为O(n^4)
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<cmath> 8 #define ll long long 9 #define DB double 10 #define mod 1000000007 11 #define eps 1e-3 12 #define inf 2147483600 13 using namespace std; 14 inline int read() 15 { 16 int x=0,w=1;char ch=getchar(); 17 while(ch<'0' || ch>'9'){if(ch=='-') w=-1;ch=getchar();} 18 while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); 19 return x*w; 20 } 21 const int N=1e3+90; 22 struct node{ 23 int u,v,c,ne; 24 }e[N]; 25 int h[N],tot,n,m,x,y; 26 void add(int u,int v,int c) 27 { 28 tot++;e[tot]=(node){u,v,c,h[u]};h[u]=tot; 29 } 30 struct kk{ 31 int id,dis; 32 bool operator<(const kk &x)const{ 33 return dis>x.dis; 34 } 35 }; 36 int d[N],v[N],ans; 37 priority_queue<kk>q; 38 void dijkstra(int s) 39 { 40 for(int i=1;i<=n;++i) d[i]=inf,v[i]=0; 41 d[s]=0;q.push((kk){s,0}); 42 while(!q.empty()) 43 { 44 int ff=q.top().id,dis=q.top().dis;q.pop(); 45 if(v[ff]) continue; 46 v[ff]=1; 47 for(int i=h[ff];i;i=e[i].ne) 48 { 49 int rr=e[i].v; 50 if(ff==x && rr==y) continue; 51 if(ff==y && rr==x) continue; 52 d[rr]=dis+e[i].c; 53 q.push((kk){rr,d[rr]}); 54 } 55 } 56 } 57 int main() 58 { 59 while(scanf("%d%d",&n,&m)!=EOF) 60 { 61 tot=0;ans=inf; 62 memset(h,0,sizeof(h)); 63 for(int i=1;i<=m;++i) 64 { 65 int x,y,c;x=read();y=read();c=read(); 66 add(x,y,c);add(y,x,c); 67 } 68 for(int i=1;i<=tot;i+=2) 69 { 70 x=e[i].u;y=e[i].v; 71 dijkstra(x); 72 ans=min(ans,d[y]+e[i].c); 73 } 74 if(ans==inf) cout<<"It's impossible."<<endl; 75 else cout<<ans<<endl; 76 } 77 return 0; 78 }
大部分情况下还是不用这个的,因为会T很惨。
喵喵~~