2016 湘潭邀请赛 c 题 Hamiltonian Path

 

现场赛的一道题

 

In ICPCCamp, there are n cities and m directed roads between cities. The i-th road going from the ai-th city to the bi-th city is ci kilometers long. For each pair of cities (u,v), there can be more than one roads from u to v. Bobo wants to make big news by solving the famous Hamiltonian Path problem. That is, he would like to visit all the n cities one by one so that the total distance travelled is minimized. Formally, Bobo likes to find n distinct integers p1,p2,...,pn to minimize w(p1,p2) + w(p2,p3) + ··· + w(pn−1,pn) where w(x,y) is the length of road from the x-th city to the y-th city. Input The input contains at most 30 sets. For each set: The first line contains 2 integers n,m (2≤ n ≤105,0≤ m ≤105). The i-th of the following m lines contains 3 integers ai,bi,ci (1≤ ai < bi ≤ n,1≤ ci ≤104). Output For each set, an integer denotes the minimum total distance. If there exists no plan, output -1 instead.

Sample Input
3 3 1 2 1 1 3 1 2 3 1 3 2 1 2 1 1 3 2
Sample Output

-1

注意题目中的条件  1<=ai < b<=n ,所以题目中给出来的边都是有向的所以点都是从小号连接到大号, 所以要想存在一条合法的路,点必须从1开始走,2,3,, n,, 

因为有重边,挑出一条最短的即可。 

 

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int head[maxn];
int e ;
const int inf =  1e8;
struct node     
{
    int to,val,next;
} edge[maxn*2];
void add_edge(int x,int y,int z)
{
    edge[e].val = z;
    edge[e].to = y;
    edge[e].next = head[x];
    head[x]= e++;
}
int main()
{
    int n , m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(head,-1,sizeof(head));
        e =0;
        int x,y,z;
        for(int i  = 1; i<=m; i++)
        {

            scanf("%d%d%d",&x,&y,&z);  add_edge(x,y,z);
        }
        int res = 0;
        int flag = 0;
        for(int i = 1; i<n; i++)
        {
            int  ans  = inf;
            for(int u = head[i]; u!=-1; u=edge[u].next)
            {
                if(edge[u].to==i+1)
                {
                    ans= min(ans,edge[u].val);
                }
            }
            if(ans==inf)
            {
                flag =1;
                break;
            }
          res+=ans;
        }
        flag == 1? printf("-1\n"):printf("%d\n",res);
    }
    return 0;
}

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值