中国邮路问题

直接上代码,以后再补思路和注释

#include
using namespace std;
const int N = 105;
const int inf = 999999999;
int matrix[N][N],mapp[N][N];
int p[N][N];
int path[N],d[N];
int sg[N];
int cont[N];
int vis[N];
int n,m;
int top;
struct node{
    int v,u,cost;
}gg[N];
void dfs(int beg){
    for(int i=1;i<=n;i++){
        if(matrix[beg][i]){
            matrix[beg][i]--;
            matrix[i][beg]--;
            dfs(i);
        }
    }
    path[top++]=beg;
}
void fleury(int beg){
    /*
    for(int i=1;i<=7;i++){
                for(int j=1;j<=7;j++){
                    printf("%d ",matrix[i][j]);
                }
                puts("");
            }
    */
    top=0;
    dfs(beg);
}
void floyed(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                //if(i==j||j==k||i==k) continue;
                if(mapp[i][j]>mapp[i][k]+mapp[k][j]){
                    p[i][j]=k;
                    mapp[i][j]=mapp[i][k]+mapp[k][j];
                }
            }
        }
    }
}
void add(int i,int j){
    int k;
    k=p[i][j];
    if(k==0) return;
    add(i,k);
    matrix[i][k]++;
    matrix[k][i]++;
    add(k,j);
    //matrix[]
}
/*
int fuck(){
    int i,j,k,maxx=inf;
    for(i=1;i<=n;i++){
        if(!g[i]) break;
    }
    if(i==n+1) return 0;
    g[i]=1;
    printf("gi=%d\n",i);
    for(j=i+1;j<=n;j++){
        if(!g[j]){
            g[j]=1;
            if(maxx>fuck()+mapp[i][j]){
                /*
                int x=i,y=j;
                while(p[x][y]){
                    int s=x;
                    x=p[x][y];
                    printf("x =%d \n",x);
//                  matrix[x][y]++;
                    //matrix[y][x]++;
                    matrix[s][x]++;
                    matrix[x][s]++;


                }
                */
                /*
                printf("i=%d,j=%d,d=%d\n",i,j,mapp[i][j]);
                con[i][j]=1;
                con[j][i]=1;
                maxx=fuck()+mapp[i][j];
            }
            g[j]=0;
        }
    }
    g[i]=0;
    return maxx;
}
*/
int adde(int cn){//直接不计较复杂度的暴力递归。将奇点进行匹配得一个最小的
    int ans=inf;
    if(cn<2)    return 0;       //奇点个数小于2,无需匹配。
    for(int i=1;i<=cn;i++){
        if(sg[i]!=0){
            for(int j=i+1;j<=cn;j++){
                if(sg[j]!=0){
                    int tem1=sg[i],tem2=sg[j];
                    sg[i]=0;
                    sg[j]=0;
                    if(ans>adde(cn-2)+mapp[tem1][tem2]){
                        cont[i]=tem2;       //第i个奇点匹配的奇点是第j个奇点
                        cont[j]=tem1;       //第j个奇点匹配的奇点是第i个奇点
                        ans=adde(cn-2)+mapp[tem1][tem2];
                    }
                    sg[i]=tem1;
                    sg[j]=tem2;
                }
            }
        }
    }
    return ans;
}
void addpath(int cn){
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=cn;i++){
        if(!vis[sg[i]]){
            vis[sg[i]]=1;
            vis[cont[i]]=1;
            while(p[sg[i]][cont[i]]){
                int sss=cont[i];
                cont[i]=p[sg[i]][cont[i]];
                matrix[sss][cont[i]]++;matrix[cont[i]][sss]++;
            }
            matrix[sg[i]][cont[i]]++;matrix[cont[i]][sg[i]]++;
        }
    }
}
void printf_path(){
    //puts("fff");
    printf("top=%d\n",top);
    for(int i=top-1;i>=0;i--){
        //printf("gg");
        printf("%d",path[i]);
        if(i) printf("->");
    }
    puts("");
}
void inif(){
    for(int i=0;i<=N;i++){
        for(int j=0;j<=N;j++){
            mapp[i][j]=(i==j)?0:inf;
        }
    }
}
int main(){
    while(~scanf("%d%d",&n,&m)){
        inif();
        int i,beg,sum=0;
        memset(matrix,0,sizeof(matrix));
        memset(d,0,sizeof(d));
        memset(sg,0,sizeof(sg));
        memset(path,0,sizeof(path));
        memset(p,0,sizeof(p));
        memset(cont,0,sizeof(cont));
        for(i=1;i<=m;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            d[a]++;
            d[b]++;
            matrix[a][b]=1;
            matrix[b][a]=1;
            mapp[a][b]=c;
            mapp[b][a]=c;
            gg[i].v=a;
            gg[i].u=b;
            gg[i].cost=c;
            sum+=c;
        }
        beg=1;
        int cnt=0;
        for(i=1;i<=n;i++){
            if(d[i]&1){
                cnt++;
                sg[cnt]=i;
                beg=i;
            }
        }
        if(!cnt){// 是欧拉图
            printf("sum=%d\n",sum);
            fleury(beg);
            printf_path();
        }
        else {           //不是欧拉图
            floyed();
            printf("sum=%d\n",sum+adde(cnt));
            addpath(cnt);
            fleury(beg);
            //puts("--------------------");
            printf_path();
        }
    }
    return 0;
}
/*
1->2->1->6->5->4->3->2->3->7->4->5->6->7->1
*/

 

你可能感兴趣的:(acm)