件名の説明:
Jzzhuと都市
テストあたりの時間制限
2秒
テストごとのメモリ制限
256メガバイト
入力
標準入力
出力
標準出力
Jzzhuがあり、国Aの社長であるnは、1から番号都市nは彼の国では。市1もありますA.の首都メートルの都市を結ぶ道路が。一つは都市から行くことができます\(u_i \)する(V_I \)\使用(およびその逆)I番目の道を、この道の長さがある\(X_I \) 。最後に、そこにあるK国の鉄道ルートは。一つは使用することができ、私の街に国の首都から行くため番目の列車のルートをS * ** i *が(およびその逆)、このルートの長さがある\(Y_I \) 。
Jzzhuは、国のお金を無駄にしたくないので、彼は電車の路線の一部を閉鎖する予定です。Jzzhuに以下の条件の下で閉じることができる列車のルートの最大数を教えてください:資本へのすべての都市からの最短経路の長さは変更してはなりません。
入力
最初の行は三つの整数が含まれているN、 M、 K(2≤ n個の ≤の \(10 ^ 5 \) ; 1≤ Mの ≤の \(3×10 ^ 5 \) ; 1≤ K ≤ \(10 ^ 5 \) )。
次のそれぞれのm行3つの整数を含む\(u_i \) 、 \(V_I \) 、 \(X_I \)(1≤ \(u_i \) 、 \(V_I \) ≤ N ; \(u_i \) ≠ \ (V_I \) ; \(1≤* \)\(X_I \) *≤ \(10 ^ 9 \) )。
次の各k個のライン2つの整数を含んでいる\(S_I及びY_I(2≤S_Iの≤nは、1≤Y_I 109 \≤) )。
すべての都市から首都への少なくとも一つの方法があることが保証されています。2つの都市間の複数の道があることを、注意してください。また、首都から同じ都市に行く複数のルートが存在することができます。
出力
出力閉じることができる列車のルートの最大数を表す単一の整数。
例
入力
コピー
5 5 31 2 12 3 21 3 33 4 41 5 53 54 55 5
出力
コピー
2
入力
コピー
2 2 31 2 22 1 32 12 22 3
出力
コピー
2
アイデア:
この問題は、単一始点最短経路であり、様々な点で静止するように1時、最短経路から出発して、実際には、交通ネットワークマップを与えることです。特定の側に直接アクセスすることは、その後1時から特定の都市に、経路長が知られています。これらの条件は、実際には既に知っているの最短経路上の様々なポイントに今一時、与えられています。今、あなたは限り保証が特殊なエッジのポイントにしても削除したとして、この変更をポイント1からの最短距離が発生していない、特殊なエッジの一部を削除したいです。そのような特別なエッジを削除することができますどのように多くまで探しています。
分析は、今の最短距離の残りの点によく知られており、各エッジの特別な考慮事項は、このエッジが直接点v、長さWが設けられています。
\(1 \) .W> D [V](Dは最短パスである)、このエッジを直接削除することができるようにポイントは、このエッジによって最短経路Vではない私に説明します。
\(2 \) 。私が最後にそれのこの側面に削除できないことを、このエッジによって到達することができ、Vへの最短経路である==のD [V]、Wか?Vに1つのだけの最短パスがある場合、Vはこれだけ特定の側への最短経路であるVに削除1の長さが増加する場合ので、それは明らかに、このエッジを削除することはできません。最短経路の数にV 1の場合は、つまり、最短Vを介して反対側に私ができる外国の特別な縁を指示するだけで、この特定の側面は、V 1への最短経路に影響を与えることなく削除することができます。
従って、最短パスの数は、各ストリップのポイントのために記録される必要があります。達成、それは最短ポイントの数、いくつかのトリッキーなダイクストラアルゴリズムの更新パスのたるみを記録する必要があります。
Vの特殊なエッジの削除に到達するための最短経路をVエッジを横断するとき、リアルタイム更新の数を覚えていた最後の特別なことに注意してください。
コード:
#include <iostream>
#include <vector>
#include <cstdio>
#include <climits>
#include <queue>
#define max_n 100005
#define INF LLONG_MAX
using namespace std;
typedef pair<long long,long long> PLL;
int n,m,k;
vector<PLL> G[max_n];
int num = 0;
long long d[max_n];//最短距离
long long deg[max_n];//最短路条数
vector<PLL> train;//特殊边
//int used[max_n<1];
/*void dijkstra(int s)
{
fill(d,d+max_n,INF);
fill(used,used+max_n,0);
d[s] = 0;
int v;
while(true)
{
int v = -1;
for(int u = 0;u<n;u++)
{
if(!used[u]&&(v==-1)||d[u]<d[v])
{
v = u;
}
}
if(v==-1) break;
used[v] = 1;
for(int u = 0;u<n;u++)
{
d[u] = min(d[u],d[v]+cost[v][u]);
}
}
}*/
void dijkstra(int s)
{
priority_queue<PLL,vector<PLL>,greater<PLL> > que;
fill(d,d+max_n,INF);
d[s] = 0;
que.push(PLL(0,s));
while(!que.empty())
{
PLL p = que.top();
que.pop();
int v = p.second;
if(d[v]<p.first) continue;
for(int i = 0;i<G[v].size();i++)
{
PLL edge = G[v][i];
if(d[edge.first]==d[v]+edge.second)//相等最短路数目加一
{
deg[edge.first]++;
}
if(d[edge.first]>d[v]+edge.second)//更新则最短路数目刷新为一
{
d[edge.first] = d[v]+edge.second;
que.push(PLL(d[edge.first],edge.first));
deg[edge.first]=1;
}
}
}
}
int main()
{
cin >> n >> m >> k;
for(int i = 0;i<m;i++)
{
int u,v;
long long w;
cin >> u >> v >> w;
G[u].push_back(PLL(v,w));
G[v].push_back(PLL(u,w));
}
for(int i = 0;i<k;i++)
{
long long to,w;
cin >> to >> w;
train.push_back(PLL(to,w));
G[1].push_back(PLL(to,w));
}
dijkstra(1);
for(int i = 0;i<train.size();i++)
{
long long v = train[i].first;
long long w = train[i].second;
if(d[v]<w)
{
num++;
}
if(d[v]==w&°[v]>1)
{
num++;
deg[v]--;
}
}
cout << num << endl;
return 0;
}
参考記事:
スカーフACM、Codeforces 449B Jzzhu及び都市(最短)、https://blog.csdn.net/qq_21057881/article/details/50602265