タイトルの説明
ご存知のとおり、TTには魔法の猫がいます。
今日、彼はステーションBで旅行の生放送を開始し、猫の旅中に魔法の猫との冒険を記録しました。TTは自宅を出発し、キャットエクスプレスでニャースター空港に向かう準備をしています。猫猫エクスプレスラインは、経済ラインと商業ラインに分けられ、スピードと価格が異なります。もちろん、商業路線は経済路線よりも高価ですが、TTは通常、経済路線しか利用できませんが、現在、TTの魔法の猫は商用路線チケットに変更され、商業路線を利用できます。TT送迎の時間はごくわずかであると想定して、TTがMiaoxing空港への最速ルートを見つけられるように手伝ってください。さもないと、飛行機に乗り遅れてしまいます!
入力
入力に複数のデータセットが含まれています。各データセットの最初の行は、N、S、Eの3つの整数(2≤N≤500、1≤S、E≤100)です。これは、駅、始点と終点(つまり、ニャー空港が配置されている駅)の総数です。 )番号。
次の行には、整数M(1≤M≤1000)が含まれています。これは、経済線のセクション数です。
次にM行があり、各行はX、Y、Zの3つの整数(1≤X、Y≤N、1≤Z≤100)です。これは、TTがステーションXとステーションYとの間で経済的なラインを利用できることを意味します。 Z分かかります。
商業ラインの次のラインの道路セグメントの数はK(1≤K≤1000)です。
次の行Kは商業行セグメントの説明であり、形式は経済行と同じです。
すべてのセクションは双方向ですが、空港に到達するには商用チケットを使用する必要がある場合があります。最適なソリューションが一意であることを確認してください。
アウトプット
データの各セットに対して、3行を出力します。1行目はTTが通過する駅(始点と終点を含む)をアクセス順に示し、2行目はTTが商用線に乗り換える駅番号です(商用線チケットを利用しない場合は引用符なしで「チケット未使用」と出力します) )、3行目は、TTがニャースター空港までに費やした合計時間です。
この質問は余分なスペースとタブを無視しないので、各回答セットの間に改行が出力されます。
入力サンプル
4 1 4
4
1 2 2
1 3 3
2 4 4
3 4 5
1
2 4 3
出力例
1 2 4
2
5
アイデア:
ダイクストラ
の2つの質問には2つの異なるルートがありますが、商用ルートがない場合は、始点から終点までの距離を直接考慮することができます。ビジネスラインが存在し、1回しか使用できないため、各ビジネスライン(a、b)を列挙できます。開始点から最短ルートを実行し、dis1配列を記録してから、終点から最短ルートを実行し、dis2配列を記録し、現在のビジネスライン(a、b)の場合、重みはwです。これは、現在のビジネスラインを通る最短パスです。最小値です(dis1 [a] + dis2 [b] + w、dis1 [b] + dis2 [a] + w)。最後に、すべての商用ラインを未使用の商用ラインと比較し、最小値をとります。
この質問の要点は出力方法です、私は鈍いので、ここで兄のコードを参照します:ポータル
コード:
#include <iostream>
#include <queue>
#include <vector>
#include <string.h>
using namespace std;
const int inf = 1e8;
const int M = 1e5+10;
const int N = 505;
vector <int> v;
struct edge
{
int to, next, w;
}es[M];
int head[N], dis1[N], dis2[N], path1[N], path2[N], vis[N];
int tot, n, m, k, s, e, ans, min1, min2, x, y, z, minpath = inf;
bool flag = false;
void add(int x,int y,int z)
{
es[++tot].to = y;
es[tot].next = head[x];
head[x] = tot;
es[tot].w = z;
}
priority_queue<pair<int, int> > q;
void dijkstra(int s,int *dis,int *path)
{
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++)
dis[i] = inf, path[i] = -1;
while (q.size())
q.pop();
dis[s] = 0;
q.push(make_pair(0, s));
while (q.size())
{
int x = q.top().second;
q.pop();
if (vis[x])
continue;
vis[x] = 1;
for (int i = head[x]; i; i = es[i].next)
{
int y = es[i].to, w = es[i].w;
if (dis[y] > dis[x] + w)
{
dis[y] = dis[x] + w;
q.push(make_pair(-dis[y], y));
path[y] = x;
}
}
}
}
int main()
{
while (scanf("%d %d %d", &n, &s, &e) != EOF)
{
ans = 0; tot = 0; minpath = inf;
memset(head, 0, sizeof(head));
scanf("%d", &m);
for (int i = 1; i <= m; i++)
{
scanf("%d %d %d", &x, &y, &z);
add(x, y, z);
add(y, x, z);
}
dijkstra(s, dis1, path1);
dijkstra(e, dis2, path2);
scanf("%d", &k);
for (int i = 1; i <= k; i++)
{
scanf("%d %d %d", &x, &y, &z);
if (dis1[x] + dis2[y] + z < minpath)
{
min1 = x;
min2 = y;
minpath = dis1[x] + dis2[y] + z;
ans = x;
}
if (dis2[x] + dis1[y] + z < minpath)
{
min1 = y;
min2 = x;
minpath = dis2[x] + dis1[y] + z;
ans = y;
}
}
if (!flag)
flag = true;
else
putchar('\n');
if(dis1[e]<minpath)
{
for (int i=e; i!=s; i=path1[i])
v.push_back(i);
v.push_back(s);
for (int i=v.size()-1; i>=1; i--)
printf("%d ",v[i]);
printf("%d\nTicket Not Used\n%d\n",v[0],dis1[e]);
}
else
{
for (int i=min1; i!=s; i=path1[i])
v.push_back(i);
v.push_back(s);
for (int i=min2; i!=e; i=path2[i])
v.insert(v.begin(),i);
v.insert(v.begin(),e);
for (int i=v.size()-1; i>=1; i--)
printf("%d ",v[i]);
printf("%d\n%d\n%d\n",v[0],ans,minpath);
}
v.clear();
}
return 0;
}