首页 > 代码库 > 17B

17B

贪心,之前先bfs判断是否联通,然后,反向建图,找一个未选择的点,找与他距离最近的点连边,因为每个点都要被选择,所以一个点离他最近的另一个点肯定也被选择,可以贪心

#include<queue>
#include<cstdio>
#include<vector>
#include<Cstring>
#include<iostream>
using namespace std;
const int inf=1<<29;
vector<int>graph[1010];
vector<int>num;
int n,m,ans,cnt,pos;
int q[1010],out[1010],head[10010],next[10010],to[10010],used[10010],w[10010];
void insert(int u,int v,int c)
{
    next[++cnt]=head[u];
    head[u]=cnt;
    to[cnt]=v;
    w[cnt]=c;
}
bool bfs(int x)
{
    int tot=1;
    queue<int>q;
    q.push(x);
    used[x]=1;
    while(!q.empty())
    {
        int u=q.front(); q.pop();
        for(int i=0;i<graph[u].size();i++)
        {
            int v=graph[u][i];
            if(!used[v]) 
            {
                tot++;
                q.push(v);
                used[v]=1;
            }
        }
    }
    return tot==n;
}
void go(int x)
{
    int u=x;
    used[pos]=1;
    while(u!=pos)
    {
        int MIN=inf,x;
        used[u]=1;
        for(int i=head[u];i;i=next[i])
        {
            int v=to[i],cost=w[i];
            if(cost<MIN)
            {
                MIN=cost;
                x=v;
            }
        }
        ans+=MIN;
        if(used[x]) break; 
        u=x;
    }
}
int main()
{
    scanf("%d",&n); int MAX=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",q+i);
        if(MAX<q[i])
        {
            MAX=q[i]; pos=i;
        }
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        int u,v,c; scanf("%d%d%d",&u,&v,&c);
        graph[u].push_back(v);
        insert(v,u,c);
//        out[u]++;
    }
    if(!bfs(pos))
    {
        cout<<-1;
        return 0;
    }
    memset(used,0,sizeof(used));
/*    for(int i=1;i<=n;i++)
    {
        if(out[i]==0) num.push_back(i);
    }*/
    for(int i=1;i<=n;i++)
    {
        if(!used[i]) go(i);
    }
    cout<<ans;
    return 0;
}

 

17B