原文链接 http://acm.hdu.edu.cn/showproblem.php?pid=4479
Shortest path
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 203 Accepted Submission(s): 67
Problem Description
There are N cities (marked by 1, 2, …, N) and M bidirectional roads in the kingdom. There may be several roads between any two cities, but there is not any road connects the same city.
Your task is to find a shortest path from city 1 to city N, and the lengths of the edges you passed by must be strictly in increasing order.
Your task is to find a shortest path from city 1 to city N, and the lengths of the edges you passed by must be strictly in increasing order.
Input
There is an integer T (1 <= T <= 500) in the first line, indicates that there are T test cases in total.
For each test case, there are two integers N (2 <= N <= 10000) and M (1 <= M <= 50000), which have the same meaning as above. Then there are M lines, and there are three integers x (1 <= x <= N), y (1 <= y <= N), and z (1 <= z <= 10000000) in each line, indicate there is a bidirectional road between city x and city y.
There are at most ten test cases that satisfy that N > 200 or M > 1000.
For each test case, there are two integers N (2 <= N <= 10000) and M (1 <= M <= 50000), which have the same meaning as above. Then there are M lines, and there are three integers x (1 <= x <= N), y (1 <= y <= N), and z (1 <= z <= 10000000) in each line, indicate there is a bidirectional road between city x and city y.
There are at most ten test cases that satisfy that N > 200 or M > 1000.
Output
For each test case, you should output the length of the shortest path you find in the above task.
If such path does not exist, you should just output “No answer” (without quotation mark) instead.
If such path does not exist, you should just output “No answer” (without quotation mark) instead.
Sample Input
4 4 6 1 2 1 1 2 2 2 3 3 2 3 1 3 4 2 4 3 6 3 2 1 2 1 2 3 1 3 1 1 2 1 2 2 2 1 1 1 2 2
Sample Output
10 No answer No answer 1
做这道提目是队长拉的一次比赛,读懂了题目,真心不知道用什么方法,后来看了题解知道用了三分,汗颜啊,三分要好好学习了,附上大神的代码。
因为满足函数凸(凹)性,所以直接用三分。
#include <iostream>
#include <cstdio>
#include <climits>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
typedef __int64 LL;
const LL maxn = 10005;
const LL maxm = 50005;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
struct node{
int u,v,len;
bool operator < (node a)const{
return len < a.len;
}
}edge[maxm];
LL dis[maxn];
int id,n,m;
struct Rec{
int v;
LL d;
}rec[maxn];
void update(int l,int r){
int index = 0;
for(int i = l; i <= r; i++){
int u = edge[i].u,v = edge[i].v,len = edge[i].len;
if( dis[u] != INF && dis[v] > dis[u] + len )
rec[index].v = v,rec[index++].d = dis[u] + len;
if( dis[v] != INF && dis[u] > dis[v] + len)
rec[index].v = u,rec[index++].d = dis[v] + len;
}
for(int i = 0; i < index; i++)
dis[rec[i].v] = min(dis[rec[i].v],rec[i].d);
}
void slove(){
memset(dis,0x3f,sizeof(dis));
//cout << dis[0] << endl;
dis[1] = 0;
for(int i = 0,j; i < m; i = j){
for( j = i+1; j < m ;j ++)
if( edge[i].len != edge[j].len)
break;
update(i,j-1);
}
}
int main(){
int t;
scanf("%d",&t);
while( t-- ){
scanf("%d%d",&n,&m);
for(int i = 0; i < m; i++)
scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].len);
sort(edge,edge+m);
slove();
if( dis[n] == INF)puts("No answer");
else printf("%I64d\n",dis[n]);
}
return 0;
}