P6175
无向图的最小环问题
论 Floyd 的奇怪用法。
主要是处理环的路径不重复的问题。
有一些技巧。
时间复杂度
代码:
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const ll N=1e2,inf=0x1f1f1f1f1f1f1f1f;
ll n,m,ans,u,v,d;
ll f[N+5][N+5],edge[N+5][N+5];
inline ll read() {
ll ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-f;ch=getchar();}
while(ch>='0'&&ch<='9') {ret=(ret<<3)+(ret<<1)+ch-'0';ch=getchar();}
return ret*f;
}
void write(ll x) {
static char buf[22];static ll len=-1;
if(x>=0) {
do{buf[++len]=x%10+48;x/=10;}while(x);
}
else {
putchar('-');
do{buf[++len]=-(x%10)+48;x/=10;}while(x);
}
while(len>=0) putchar(buf[len--]);
}
void writeln(ll x) {
write(x);putchar('\n');
}
int main() {
n=read();m=read();
memset(f,0x1f,sizeof(f));
memset(edge,0x1f,sizeof(edge));
for(ll i=1;i<=n;i++) edge[i][i]=f[i][i]=0;
for(ll i=1;i<=m;i++) {
u=read();v=read();d=read();
f[u][v]=f[v][u]=min(f[u][v],d);
edge[u][v]=edge[v][u]=min(edge[u][v],d);
}
ans=inf;
for(ll k=1;k<=n;k++) {
for(ll i=1;i<k;i++) {
for(ll j=i+1;j<k;j++) {
ans=min(ans,f[i][j]+edge[i][k]+edge[k][j]);
}
}
for(ll i=1;i<=n;i++) {
for(ll j=1;j<=n;j++) {
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
}
}
if(ans>=inf) printf("No solution.");
else write(ans);
return 0;
}