D. Jzzhuと都市
テストあたりの制限時間:2秒
テストごとのメモリ制限:256メガバイト
入力:標準入力
出力:標準出力
Jzzhuがあり、国Aの社長です\(N \)から数え都市\(1 \)がする\(N \)彼の国インチ 市\(1 \)は、 Aの首都でもあります\(m個\)都市を結ぶ道路が。一つは都市から行くことができます\(u_i \)する(V_I \)\使用(およびその逆)\(私は\)番目の道を、この道の長さがある\(X_I \) 。最後に、そこにある\(K \)国の鉄道ルートは。一つは使用することができます\(私は\)都市への国の首都から行くため番目の列車のルートを\(S_I \) (およびその逆)、このルートの長さがある\(Y_I \) 。
Jzzhuは、国のお金を無駄にしたくないので、彼は電車の路線の一部を閉鎖する予定です。Jzzhuに以下の条件の下で閉じることができる列車のルートの最大数を教えてください:資本へのすべての都市からの最短経路の長さは変更してはなりません。
入力
最初の行は三つの整数が含ま\(N、M、K(10 ^ 5≤2≤nは、1≤M 5 \ cdot10 ^ 3≤1≤K 5 ^ 10≤)\)。
次の各m個の行は三つの整数が含まれて\(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≤10 ^ 9)\) 。
すべての都市から首都への少なくとも一つの方法があることが保証されています。2つの都市間の複数の道があることを、注意してください。また、首都から同じ都市に行く複数のルートが存在することができます。
出力
出力閉じることができる列車のルートの最大数を表す単一の整数。
例
入力
5 5 3
1 2 1
2 3 2
1 3 3
3 4 4
1 5 5
3 5
4 5
5 5
出力
2
入力
2 2 3
1 2 2
2 1 3
2 1
2 2
2 3
出力
2
問題の意味
ある都市\(m個\)道路及び(k個の\)\鉄道、各鉄道の出発点は、接続されています。各点の始点までの最短経路の長さを変更することなく、今の要件、尋ねるレールの最大数を除去することができ、鉄道の一部を除去します
考え
道路及び鉄道構成図が一緒に入れ、次いで、最短での最短の実行プロセスの各点で記録を実行する(ポイントは、多くの最短パスが含まれる方法です)
鉄道は、条件を削除できます。
- 最短経路点の開始点に開始点は、鉄道の長さをこの点に等しくなるようにした場合、それは入院の点がより大きいか否かを判断する\(1 \)を超える場合には、\(1 \) 、鉄道を除去することも可能である(到達します最短経路)は複数のポイントであります
- 出発点への最短経路の長さと開始点は鉄道よりも小さいです
コード
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ms(a,b) memset(a,b,sizeof(a))
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e6+10;
const int mod=1e9+7;
const int maxm=1e3+10;
using namespace std;
struct edge
{
int to,Next;
ll value;
}Edge[maxn];
int head[maxn];
int tot;
inline void add_edge(int u,int v,ll w)
{
Edge[tot].to=v;
Edge[tot].Next=head[u];
Edge[tot].value=w;
head[u]=tot++;
}
struct node
{
int u;
ll d;
bool operator < (const node & dui) const{return d>dui.d;}
};
int ss[maxn];
ll yy[maxn];
ll dis[maxn];
int in[maxn];
inline void dijkstra(int s)
{
priority_queue<node>que;
que.push(node{s,0});
dis[s]=0;
while(!que.empty())
{
node res=que.top();
que.pop();
int u=res.u;ll d=res.d;
if(d!=dis[u])
continue;
for(int i=head[u];~i;i=Edge[i].Next)
{
int v=Edge[i].to;
ll w=Edge[i].value;
if(dis[v]==dis[u]+w)
in[v]++;
if(dis[v]>dis[u]+w)
in[v]=1,dis[v]=dis[u]+w,que.push(node{v,dis[v]});
}
}
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("/home/wzy/in", "r", stdin);
freopen("/home/wzy/out", "w", stdout);
srand((unsigned int)time(NULL));
#endif
ios::sync_with_stdio(false);
cin.tie(0);
int n,m,k;
cin>>n>>m>>k;
for(int i=0;i<=n;i++)
dis[i]=INF;
ms(head,-1);
int x,y;
ll z;
while(m--)
cin>>x>>y>>z,add_edge(x,y,z),add_edge(y,x,z);
for(int i=0;i<k;i++)
cin>>ss[i]>>yy[i],add_edge(1,ss[i],yy[i]),add_edge(ss[i],1,yy[i]);
dijkstra(1);
ll ans=0;
for(int i=0;i<k;i++)
{
if(yy[i]==dis[ss[i]]&&in[ss[i]]>1)
ans++,in[ss[i]]--;
if(yy[i]>dis[ss[i]])
ans++;
}
cout<<ans<<endl;
#ifndef ONLINE_JUDGE
cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s."<<endl;
#endif
return 0;
}