2012黑龙江省赛J题最小均值圈

有重边,有自环,卡精度.

View Code
/*
Source Code
Problem: 1001
Username: 2010201211
Run Time: 304MS
Memory: 1208K
Language:C++
JudgeStatus: Accepted
Author:MarkLiu
*/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <stdio.h>
#include <string.h>
using namespace std;

const int N = 201;
const int INF = 1<<20;
int n,d[N][N],kd[N][N],m;
int g[N][N],gn[N];
double karp(){
    for(int i=0;i<=n;i++)
        for(int j=0;j<n;j++)
            kd[i][j]=INF;
    for(int i=0;i<n;i++)
        kd[0][i]=0;
    for(int i=1;i<=n;i++)
        for(int j=0;j<n;j++)
            if(kd[i-1][j]==INF) continue;
            else for(int k=gn[j]-1;k>=0;k--)
                kd[i][g[j][k]] = min(kd[i][g[j][k]],kd[i-1][j]+d[j][g[j][k]]);
    //cout << "debug" << endl;
    double minc=1e20;bool est=false;
    for(int i=0;i<n;i++){
        double mc=-1e20;
        if(kd[n][i]==INF) continue;
        for(int j=0;j<n;j++)
            if(kd[j][i]!=INF){
                mc=max(mc,1.0*(kd[n][i]-kd[j][i])/(n-j));
                est=true;
            }
        minc=min(minc,mc);
    }
    if(!est) minc=1e50;
    return minc;
}

int main(){
    //freopen("in.txt","r",stdin);
    int a,b,c;
    while(scanf("%d%d",&n,&m)!=EOF){
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++){
                if(i==j) d[i][j]=INF;
                else d[i][j]=INF;
            }

        while(m--){
            scanf("%d%d%d",&a,&b,&c);
            if(c<d[a-1][b-1])
                d[a-1][b-1]=c;
        }
        memset(g,0,sizeof(g));
        memset(gn,0,sizeof(gn));
        for(int i=0;i<n;i++){
            int cnt=0;
            for(int j=0;j<n;j++){
                if(d[i][j]!=0 && d[i][j]!=INF){
                    g[i][cnt++]=j;
                }
            }
            gn[i]=cnt;
        }
        /*for(int i=0;i<n;i++){
            for(int j=0;j<gn[i];j++){
                printf("%d ",g[i][j]);
            }
            cout << endl;
        }*/
        double res=karp();
        if(res==1e50) printf("INF\n");
        else{
            printf("%.3lf\n",res+1e-9);
        }

    }
    return 0;
}
/*
Sample Input:
3 3
1 2 2
2 3 2
3 1 1
8 7
1 1 14
8 1 969
5 3 518
3 5 948
7 2 962
8 2 221
1 1 935
3 3
2 3 2
3 2 2
1 1 1
Sample Output:
1.667
14.000
1.000
*/
原文地址:https://www.cnblogs.com/markliu/p/2536434.html