hust 1019 A dangerous trip

题目描述

N cities are connected by a network of M one-way roads. It is known that
these roads do not cross outside the cities. The numeration of the cities and
the roads starts from 1. One day, Haryy Potter must make a dangerous trip from
city 1 to city N. Because there may have many monsters along the roads, he wants
to finish this trip as soon as possible. Luckily, he knows a specil magic which
can change the length of a road to half of the original length. But his magic is
limited, and he can only use this magic once. Now give you the network, try to
find the minumum time he can finish this dangerous trip.

输入

The first line contains an integer T,which means there are T test cases to be
followed. For each test case: the first line contains two integer n and m, which
are the number of vertices and edges int the network. Following the next m
lines: each line describes an edge with three integers in the format: i, j,
Cij.(cij is the time Haryy Potter must pay for
from the city i to j if he don’t use magic) (0 < n <= 104, 0
< m < 105, 0 < i, j <= n, 0 <
cij < 105)

输出

For each test case, output the minimum time he must pay for this dangerous
trip.

样例输入

2
4 4
1 2 8
1 3 6
2 4 18
3 4 20
4 4
1 2 8
1 3 6
2 4 18
3 4 21

样例输出

16
16.5

一开始我是这样想的,d1[i]表示从起点到i的最短路,d2[i]表示从终点到i的最短路,然后枚举把每条边减半的情况,求最小值,但不知道为什么总是WA,于是在学长的点拨之下,改用dp,d1[i]表示不用魔法,d2[i]表示使用魔法,这样转移方程为d2[map[x][i].id]=min(d2[map[x][i].id],min(d1[x]+map[x][i].cost/2,d2[x]+map[x][i].cost));
当然这个转移方程是用vector写的,具体的还是看程序吧


#include<iostream>
#include<cstdio>
#include<vector>
#include<utility>
#include<queue>
#include<cstring>
using namespace std;
const int N=100001;
typedef pair<long long ,int>pii;
priority_queue<pii,vector<pii>,greater<pii> >q;
struct node
{
int id;
long long cost;
};
vector<node>map[N];
long long d1[N],d2[N];
long long tempmin1,Min,tempmin2;
int n;
bool vis[N];
void dijkstra1(int k)
{
for (int i=1;i<=n;i++) d1[i]=d2[i]=(i==k?0:999999999999);
memset(vis,0,sizeof(vis));
q.push(make_pair(d1[k],k));
while(!q.empty())
{
pii u=q.top();q.pop();
int x=u.second;
if (!vis[x])
{
vis[x]=true;
for (int i=0;i<map[x].size();i++){
if(d1[map[x][i].id]>d1[x]+map[x][i].cost)
{
d1[map[x][i].id]=d1[x]+map[x][i].cost;
q.push(make_pair(d1[map[x][i].id],map[x][i].id));
}
d2[map[x][i].id]=min(d2[map[x][i].id],min(d1[x]+map[x][i].cost/2,d2[x]+map[x][i].cost));//这里就是转移方程
if (map[x][i].id==n) Min=min(d2[map[x][i].id],Min);//只有当==n的时候才更新
}
}
}
}

int main()
{
int t,m,x,y;
long long z;
int a[N],b[N];
long long c[N];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for (int i=0;i<=n;i++) {map[i].clear();}
for (int i=0;i<m;i++)
{
scanf("%d%d%lld",&x,&y,&z);
node temp;
a[i]=x;b[i]=y;c[i]=z*10;
temp.id=y;temp.cost=z*10;
map[x].push_back(temp);
}
Min=9999999999999;
dijkstra1(1);
if (Min%10==0)printf("%lld\n",Min/10);
else printf("%lld.%lld\n",Min/10,Min%10);
}
return 0;
}

hust 1019 A dangerous trip

时间: 2024-10-11 01:33:56

hust 1019 A dangerous trip的相关文章

暑假集训-基础图论

5 / 37 Problem A HUST 1019 A dangerous trip 10 / 71 Problem B HUST 1631 Road System     Problem C UVALive 3523 Knights of the Round Table   1 / 5 Problem D UVALive 5135 Mining Your Own Business 1 / 1 Problem E UVALive 4287 Proving Equivalences 0 / 2

HUST 1588 辗转数对

1588 - 辗转数对 时间限制:1秒 内存限制:128兆 155 次提交 27 次通过 题目描述 假设当前有一个数对(a, b),我们可以通过一步将这个数对变为一个新数对(a + b, b)或者是(a, a + b).初始的数对为(1, 1),你的任务是找到一个数字k,即通过最少的步数使得这个数对中至少一个数字等于n. 输入 输入包括多组数据,每组数据包括一行,每行有一个整数n. 输出 每组数据输出一行,每行一个整数n. 样例输入 5 3 样例输出 3 2 提示 第一个样例的方法是 (1,1)

HUST 1698 - 电影院 组合数学 + 分类思想

http://acm.hust.edu.cn/problem/show/1698 题目就是要把一个数n分成4段,其中中间两段一定要是奇数. 问有多少种情况. 分类, 奇数 + 奇数 + 奇数 + 奇数 奇数 + 奇数 + 奇数 + 偶数 偶数 + 奇数 + 奇数 + 奇数 偶数 + 奇数 + 奇数 + 偶数 然后奇数表达成 2 * a - 1这个样子,就能列出方程. 然后就是类似于解a1 + a2 + a3 + a4 = x的问题了. #include <cstdio> #include &l

POJ 1041 John&#39;s trip 无向图的【欧拉回路】路径输出

欧拉回路第一题TVT 本题的一个小技巧在于: [建立一个存放点与边关系的邻接矩阵] 1.先判断是否存在欧拉路径 无向图: 欧拉回路:连通 + 所有定点的度为偶数 欧拉路径:连通 + 除源点和终点外都为偶数 有向图: 欧拉回路:连通 + 所有点的入度 == 出度 欧拉路径:连通 + 源点 出度-入度=1 && 终点 入度 - 出度 = 1 && 其余点 入度 == 出度: 2.求欧拉路径 : step 1:选取起点(如果是点的度数全为偶数任意点为S如果有两个点的度数位奇数取一

HUST 1017 - Exact cover (Dancing Links 模板题)

1017 - Exact cover 时间限制:15秒 内存限制:128兆 自定评测 5584 次提交 2975 次通过 题目描述 There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is a selection of rows such that every column has a 1 in exactly one of the selected rows. Try to find o

poj1734 Sightseeing trip

Sightseeing trip Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6919   Accepted: 2646   Special Judge Description There is a travel agency in Adelton town on Zanzibar island. It has decided to offer its clients, besides many other attra

1019 逆序数

1019 逆序数 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4.给出一个整数序列,求该序列的逆序数. Input 第1行:N,N为序列的长度(n <= 50000) 第2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9) Ou

poj 1019 Number Sequence (数学)

链接:http://poj.org/problem?id=1019 分析:就是计数的问题..可以先算出112123...m共有多少位,具体式子看代码..然后二分取一个最大的小于n的m,接下来考虑123...m有多少位,再二分一下求解就可以了..具体式子还是看代码.. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 typedef long long

codevs——1019 集合论与图论

1019 集合论与图论 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 集合论与图论对于小松来说是比数字逻辑轻松,比数据结构难的一门专业必修课.虽然小松在高中的时候已经自学过了离散数学中的图论,组合,群论等知识.但对于集合论,小松还是比较陌生的.集合论的好多东西也涉及到了图论的知识. 在第四讲的学习中,小松学到了“有序对”这么一个概念,即用<x, y>表示有序对x和y.要注意的是有序对<x, y>