题目
众所周知,2018-1-31是个神奇的日子。这天晚上,不仅有百年一遇的蓝月,还有千年一遇的奇观——wyf梦游。
具体地说,wyf梦见自己在一张奇怪的图中。这张图有n个结点,m条带权有向边。此后死,wyf正在结点1,而教室竟然在遥远的结点n!
wyf自然是很害怕迟到的,于是他想知道从1到n的最短路有多长。
他还想知道:(怎么那么多想知道的)若能将任意一条边的边权变为0,从1到n的最短路有多长。
Input
第一行两个整数n, m代表点数和边数。
接下来的m行每行输入三个整数,代表一条边的起点,终点和边权。
Output
输出包含两个整数
第一个:代表在原图中的最短路长度。
第二个:代表能够将任意一条边的边权变为0的情况下的最短路长度。
Special Judge
正确输出第一个答案,获得40%的分数;
正确输出第二个答案,获得60%的分数;
如果不知道某个答案,请输出0,至少可以得分。
↑↑↑↑↑题目大概就是这样了,一道非常明显的...呃....最短路问题。在哪里..在那里见过你..听过师兄讲过
就第一步做对最短路长度(邻接表存图),第二步做对第二个问(用队列来做),第三步考虑优化程序(优先队列)
附代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e6 + 5;
struct Main {
struct Vtx {
int To;
long long Wgt;
Vtx *Next;
Vtx(void) : Next(NULL) {}
Vtx(int To, long long Wgt) :
To(To), Wgt(Wgt), Next(NULL) {}
};
struct VtxHead : Vtx {
Vtx *Head;
long long Dist;
void Grow(int To, long long Wgt)
{
if (Head) Next =
Next->Next = new Vtx(To, Wgt);
else Head = Next = new Vtx(To, Wgt);
}
VtxHead(void) : Head(NULL), Dist(LLONG_MAX) {}
} G[MAXN], AntiG[MAXN];
struct Unit {
int u;
long long Dist;
bool operator < (const Unit &x) const
{
return Dist > x.Dist;
}
};
inline void Search(VtxHead *Graph, int Source)
{
priority_queue<Unit> Travel;
Travel.push( (Unit) { Source, 0 } );
Graph[Source].Dist = 0;
while (!Travel.empty()) {
int From = Travel.top().u;
long long CrtDist = Travel.top().Dist;
Travel.pop();
if (CrtDist <= Graph[From].Dist)
for (register Vtx *i = Graph[From].Head; i; i = i->Next) // i->To
if (Graph[From].Dist + i->Wgt < Graph[i->To].Dist) {
Graph[i->To].Dist = Graph[From].Dist + i->Wgt;
Travel.push( (Unit) { i->To, Graph[i->To].Dist } );
}
}
}
Main(void)
{
int n, m;
scanf("%d %d", &n, &m);
while (m--) {
int u, v;
long long Wgt;
scanf("%d %d %lld", &u, &v, &Wgt);
G[u].Grow(v, Wgt);
AntiG[v].Grow(u, Wgt);
}
Search(G, 1);
Search(AntiG, n);
printf("%lld\n", G[n].Dist);
long long MinDist = G[n].Dist;
for (register int i = 1; i <= n; ++i)
for (register Vtx *j = G[i].Head; j; j = j->Next)
if (G[i].Dist + AntiG[j->To].Dist < MinDist)
MinDist = G[i].Dist + AntiG[j->To].Dist;
printf("%lld\n", MinDist);
}
};
int main(void)
{
delete new Main;
return 0;
}