程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UVA 10600 - ACM Contest and Blackout (次小生成樹)

UVA 10600 - ACM Contest and Blackout (次小生成樹)

編輯:C++入門知識

/* 次小生成樹的問題,  方法:求出最小生成樹 並且標記路徑   F[i][j] 代表最小生成樹中i->j中最大的一條邊  如果map(i,j)> F[i][j]

則替換這條邊  枚舉每一條不在最小生成樹中的邊  替換之 找出最小的。

*/

 


#include<cstdio>

#include<cstring>
#define INF 1<<30
int map[110][110],n,m;
int vis[110],use[110][110],low[110];
int pre[110],F[110][110];
int max(int x,int y)
{
    return x>y?x:y;
}
int prim(int s,int t)
{
    int ans=0;
    memset(pre,-1,sizeof(pre));
    pre[s] = -1;
    memset(F,0,sizeof(F));
    for(int i = 1; i <= n; i++)
    {
        vis[i] = 0;
        low[i] = INF;
    }
    low[1] = 0;
    //vis[s] = 1;
    for(int i = 1; i <= n; i++)
    {
        int temp = INF,tp=-1;
        for(int j = 1; j <= n; j++)
            if(!vis[j]&&temp>low[j])
            {
                tp = j;
                temp=low[j];
            }
        if(tp==-1) continue;
        int k = tp;
        int v = pre[k];
        if(v!=-1)
        {
            use[k][v]=use[v][k]=2;
            for(int j = 1; j <= n; j++)
                if(vis[j])
                    F[j][k] = max(F[j][v],map[v][k]);
        }
        vis[k] = 1;
        ans+=low[k];
        for(int j = 1; j <= n; j++)
            if(!vis[j]&&low[j]>map[k][j])
            {
                low[j] = map[k][j];
                pre[j] = k;
            }
    }
    return ans;
}
int second_mst(int x)
{
    int res=x,ans=INF;
    for(int i = 1; i <= n; i++)
    for(int j = 1; j <= n; j++)
    if(use[i][j]==1&&map[i][j]!=INF&&F[i][j]!=INF)
    {
        if(res+map[i][j]-F[i][j] < ans)
        ans = res+map[i][j]-F[i][j];
        //printf("%d.%d.\n",F[i][j],map[i][j]);
    }
    return ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i = 0; i<=n; i++)
            for(int j = 0; j<=n; j++)
                map[i][j] = INF;
        memset(use,0,sizeof(use));
        int x,y,z;
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            map[x][y]=map[y][x]=z;
            use[x][y]=use[y][x]=1;
        }
        int ans=prim(1,n);
        int ans1=second_mst(ans);
        printf("%d %d\n",ans,ans1);
    }
    return 0;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved