online_judge_1249

183 篇文章 0 订阅
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <limits>

using namespace std;

const int M = 100100;
const int N = 1005;

struct E
{
    int s;
    int e;
    int cost;
    bool operator < (const E &e) const
    {
        return cost < e.cost;
    }
};

int Kruskal(E *edge, int m, int *id, int *Tree, int n);
int findRoot(int *Tree, int x);
int SecondTree(E *edge, int pos, int *Tree, int m, int n);

int main()
{
    int id[M];
    int Tree[N];
    E edge[M];
    int t,n,m,i;
    int res,r;
    cin>>t;
    while(t--)
    {
        res = -1;
        cin>>n>>m;
        for(i=0; i<m; ++i)
        {
            cin>>edge[i].s>>edge[i].e>>edge[i].cost;
        }
        sort(edge, edge+m);
        res = Kruskal(edge, m, id, Tree, n);
        if(res == -1)
        {
            cout<<-1<<endl;
            continue;
        }
        res = numeric_limits<int>::max();
        for(i=0; i<n-1; ++i)
        {
            r = SecondTree(edge, id[i], Tree, m, n);
            if(r!=-1 && r<res)
                res = r;
        }
        if(res == numeric_limits<int>::max())
            cout<<-1<<endl;
        else
            cout<<res<<endl;
    }
    return 0;
}

int findRoot(int *Tree, int x)
{
    if(Tree[x]==-1)
        return x;
    else
    {
        int tmp = findRoot(Tree, Tree[x]);
        Tree[x] = tmp;
        return tmp;
    }
}

int Kruskal(E *edge, int m, int *id, int *Tree, int n)
{
    int a,b,i,cnt = 0,res = 0;
    for(i=0; i<N; ++i)
    {
        Tree[i] = -1;
    }
    for(i=0; i<m; ++i)
    {
        if(cnt == n-1)
            break;
        a = findRoot(Tree, edge[i].s);
        b = findRoot(Tree, edge[i].e);
        if(a!=b)
        {
            Tree[a] = b;
            id[cnt++] = i;
            res += edge[i].cost;
        }
    }
    if(cnt != n-1)
        return -1;
    return res;
}

int SecondTree(E *edge, int pos, int *Tree, int m, int n)
{
    int a,b,i,cnt = 0,res = 0;
    for(i=0; i<N; ++i)
    {
        Tree[i] = -1;
    }
    for(i=0; i<m; ++i)
    {
        if(cnt == n-1)
            break;
        if(i == pos)
            continue;
        a = findRoot(Tree, edge[i].s);
        b = findRoot(Tree, edge[i].e);
        if(a!=b)
        {
            Tree[a] = b;
            cnt++;
            res += edge[i].cost;
        }
    }
    if(cnt!=n-1)
        return -1;
    return res;
}

/*实在是不知道为什么这种做法提交总是错误……
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <limits>

using namespace std;

const int N = 101;

struct E
{
    int next;
    int cost;
    bool operator < (const E &e) const
    {
        return cost < e.cost;
    }
};

int minSecTree(int *a, int n, vector<E> *edge, bool *mark, int v);

int main()
{
    int a[N];
    bool mark[N];
    vector<E> edge[N];
    int t,n,m,i,j;
    int s,e,w;
    int res;
    cin>>t;
    while(t--)
    {
        res = -1;
        cin>>n>>m;
        for(i=0; i<=n; ++i)
        {
            edge[i].clear();
        }
        for(i=0; i<m; ++i)
        {
            cin>>s>>e>>w;
            E tmp;
            tmp.cost = w;
            tmp.next = e;
            for(j=0; j<edge[s].size(); ++j) //去除重边
            {
                if(edge[s][j].next == e)
                    continue;
            }
            edge[s].push_back(tmp);
            tmp.next = s;
            edge[e].push_back(tmp);
        }
        for(i=1; i<=n; ++i)
            sort(edge[i].begin(), edge[i].end());
        for(i=1; i<=n; ++i)
        {
            if(minSecTree(a,n,edge,mark,i)!=-1 && (res==-1 || minSecTree(a,n,edge,mark,i)<res))
                res = minSecTree(a,n,edge,mark,i);
        }
        cout<<res<<endl;
    }
    return 0;
}

int minSecTree(int *a, int n, vector<E> *edge, bool *mark, int v)
{
    int i,j,numE = 0,res = 0;
    int mm, mindex;
    if(edge[v].size() <= 1)
        return -1;
    memset(mark, false, sizeof(mark));
    for(i=1; i<=n; ++i)
    {
        a[i] = numeric_limits<int>::max();
    }
    a[v] = 0;
    for(i=1; i<edge[v].size(); ++i)
    {
        a[edge[v][i].next] = edge[v][i].cost;
    }
    mark[v] = true;
    res += edge[v][1].cost;
    numE++;
    v = edge[v][1].next;
    mark[v] = true;
    for(i=1; i<n-1; ++i)
    {
        for(j=0; j<edge[v].size(); ++j)
        {
            if(mark[edge[v][j].next]==false && edge[v][j].cost<a[edge[v][j].next])
                a[edge[v][j].next] = edge[v][j].cost;
        }
        mm = numeric_limits<int>::max();
        mindex = -1;
        for(j=0; j<n; ++j)
        {
            if(mark[j]==false && a[j]<mm)
            {
                mm = a[j];
                mindex = j;
            }
        }
        res += mm;
        numE++;
        if(mindex == -1)
            return -1;
        v = mindex;
        mark[v] = true;
    }
    if(numE == n-1)
        return res;
    return -1;
}
*/


 

下面原创的算法实在不知道错在哪里了。。。。OJ就是这点让人郁闷,,,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值