[説明] CJOI2019貿易(最短+自然)
行動のポイントにCJ黄、口の中のような高校の選手を評価する方法は?
テン過去11が書き始めた誰かが巻き取り終えるために私を促したとき...この質問は少し恥ずかしがり屋です
[問題の説明]
\(2020 \)年、資本主義世界初の\(のp \)金融危機の時代。
皿の調理国の地球の遠端はまた、いくつかのインパクトとなっています。
経済発展のペースを加速するために、政府は国の大規模な地元の関税を削減する予定。
関税削減の後、と\(X \)限り有料として万元領域に到達するには、\(1 \)税百万円となりました。
しかし、このディレクティブに抵抗する最高経営責任者(CEO)の一部の地域では、彼らはそれで、つまり、本来の税額を維持することを発表しました\(X \)支払う必要があり、これらの領域に到達するために万元(\ \ lceilの\のFRAC {X } {K} \ rceil \ )元税。
全国各地\(m個\)互いに道路リンク。
今私はビジネスマンからお金を取りたい\(S \)に達するために\(T \)グラウンド。彼はすべてを達するために税金を支払ったことが期待さ(t \)\よりも低い領域、あまりないの合計金額(\ w)は\万人。だから、彼は彼は出発の最小値を持参してくださいどのくらいのお金、計算助けてください?
(地域をする必要はありません(S \)\税)
もちろんから\(T \)になりまし市の減税ではない、非常によく起因する都市のうち減税に、プッシュバックし始めました
であることが判明追加、プッシュバック(U-> V \)\、そして今私が知っている\(V \)の重みを、求めている\(uと\)される(\ DIS)\
約の溶液(X \)\式
\ [X- \ lceil \ dfrac XK
\ \ rceil = B] 溶液アウト
の\ [X = \ lceil \ dfrac {KB} {K-1} \ rceil \]
以来(DIS \)\アレイが単調に増加するが、それは貪欲をDijとすることができます
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=5e5+5;
struct E{
int to,nx,w;
E(){to=nx=w=0;}
E(const int&a,const int&b,const int&c){to=a;nx=b;w=c;}
}e[maxn<<2];
int head[maxn];
int cnt;
int S,T,W;
int n,m,k;
int j[maxn];
inline void add(const int&fr,const int&to,const int&f){
int w=-1;
if(!j[fr]) w=k;
e[++cnt]=E(to,head[fr],w);
head[fr]=cnt;
if(f)add(to,fr,0);
}
ll d[maxn];
int last[maxn];
const ll inf=2e17;
typedef pair < ll , int > Pll;
priority_queue < Pll , vector < Pll > , greater < Pll > > q;
inline int getw(const ll&x,const ll&mu){
if(mu==-1)return x+1;
return (x*mu)/(mu-1LL)+bool((x*mu)%(mu-1));
}
inline int spfa(){
for(register int t=1;t<=n;++t) d[t]=inf;
d[T]=W;
q.push(make_pair(d[T],T));
while(q.size()){
register auto now=q.top();
q.pop();
if(now.second==S)break;
for(register int t=head[now.second],t1;t;t=e[t].nx){
t1=getw(d[now.second],e[t].w);
if(d[e[t].to]>t1){
d[e[t].to]=t1;
last[e[t].to]=now.second;
q.push(make_pair(d[e[t].to],e[t].to));
}
}
}
return d[S];
}
int main(){
//freopen("trade.in","r",stdin);
//freopen("trade.out","w",stdout);
n=qr();m=qr();k=qr();
for(register int t=1;t<=n;++t) j[t]=qr();
for(register int t=1;t<=m;++t) add(qr(),qr(),1);
S=qr();T=qr();W=qr();
printf("%d\n%d",spfa(),S);
for(register int t=last[S];t;t=last[t])
printf("->%d",t);
return 0;
}