次小生成树

最小生成树基础上,在添加边的时候,多处理一个len。。。len【i】【j】表示从i到j成环的时候应该删除这个环里最长的边的边长,其实就是每次加边时候,如果边的两边两个点uv祖宗不相连,那么加这条边,这条边是当前最大的边,就是说,u的祖宗和v的祖宗所链接的点及自己(最初加边时加自己到自己的边)互相之间的len都是现在这条边的权值。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 210;
const int maxm = maxn*maxn;
int n,m,tt,tot ,root[maxn];
int len[maxn][maxn],head[maxn];
bool vis[maxn][maxn];
char c[2];
struct  node{
    int from,to,w;
    bool operator < (const node &b)const{
        return w < b.w;
    }
}edges[maxm];

struct no{
    int v,next;
}eg[maxm];
void add(int u,int v){
    eg[tt].v = v;eg[tt].next=head[u];head[u]=tt++;
}
void init(){
    scanf("%d%d",&n,&m);
    memset(vis,false,sizeof(vis));
    memset(head,-1,sizeof(head));
    tot = tt =  0;
    for(int i = 0; i <= n ; i++)    root[i] = i;
    for(int i = 1 ; i <= m ; i++){
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        add(u,v);
        add(u,u);
        edges[tot].from = u;edges[tot].to = v;edges[tot].w = w;
        tot++;

    }
    sort(edges,edges+tot);
}
int findroot(int x){
    return x==root[x]?x:root[x]=findroot(root[x]);
}
void kru(){
    int ans = 0;
    for(int i = 0 ; i < tot ;i++){
        int x = findroot(edges[i].to),y = findroot(edges[i].from);
        if(x == y)  continue;
        else{
            ans+=edges[i].w;
            vis[edges[i].from][edges[i].to] = true;
            for(int s1 = head[x];s1!=-1;s1 = eg[s1].next)
                for(int s2 = head[y];s2!=-1;s2 = eg[s2].next)
                    len[eg[s1].v][eg[s2].v] = len[eg[s2].v][eg[s1].v]=edges[i].w;

            root[x] = root[y];
        }
    }
    //printf("ans = = %d\n",ans);
    int semst = (1<<30);
    for(int i = 0; i < tot ; i++){
        if(!vis[edges[i].from][edges[i].to]){//加入这条没在mst里面的边
            semst = min(semst,ans-len[edges[i].from][edges[i].to]+edges[i].w);
           // cout << "semet = "<<semst <<endl;
        }
    }
    if(semst == ans)    printf("Not Unique!\n");
    else    printf("%d\n",ans);
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        init();
        kru();
    }
}
阅读更多
版权声明:转我原创记得说你是我的脑残粉哟 https://blog.csdn.net/zjy2015302395/article/details/54747888
个人分类: acm 基本算法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭