LOJ10072

LOJ10072

这题,N这么小,可以想到 O(N3) O ( N 3 ) 枚举三个点 i,j,k i , j , k
此时贪心想法,构成的环最小为 w[i][k]+w[k][j]+min_w[i][j] w [ i ] [ k ] + w [ k ] [ j ] + m i n _ w [ i ] [ j ] ( 最 短 路 )
可是显然,要求 i>j i − − > j 的最短路内不包含 k k
So,恰好floyd呗!

每次不是从小到大枚举支点k嘛?此时所有最短路显然都不包括k(除了原图的边)
所以边刷floyd边更新答案即可
(可以“选选排”枚举)

#include
#define gt() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++)
#define LL long long
using namespace std;
static char buf[1000000],*p1=buf,*p2=buf;
const int maxn=105;
int n,m,g[maxn][maxn],f[maxn][maxn],fa[maxn][maxn],Ans,INF,id[maxn];
int read(){
    int ret=0;char ch=gt();
    while(ch<'0'||ch>'9') ch=gt();
    while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=gt();
    return ret;
}
void work(int x,int y){if(!fa[x][y]) return;work(x,fa[x][y]),id[++id[0]]=fa[x][y],work(fa[x][y],y);}
int main(){
    n=read(),m=read();
    memset(g,63,sizeof g),memset(f,63,sizeof f),Ans=INF=f[0][0];
    for(int i=1;i<=m;i++){
        int x=read(),y=read(),z=read();
        if(z
    }
    for(int k=1;k<=n;k++){
        for(int i=1;i
          for(int j=1;j
            Ans=f[i][j]+g[i][k]+g[k][j];
            id[id[0]=1]=i,work(i,j),id[++id[0]]=j,id[++id[0]]=k;
          }
        for(int i=1;i<=n;i++)if(i!=k)
          for(int j=1;j<=n;j++)if(i!=j&&j!=k&&f[i][k]+f[k][j]
    }
    if(Ans==INF) return puts("No solution."),0;
    for(int i=1;i
    return 0; 
}

你可能感兴趣的:(floyed,LOJ)