描述
P老师要去旅行,旅行的途中会经过n个城市(城市按1~n编号),从i城市到j城市距离为d,p老师想要走最短的路,但是p老师远没有这么简单,p老师不仅想要走最短的路,还想要带女朋友一路走,可是女朋友方向感很差,如果不是按城市编号顺序前进,每经过一个城市p老师的女朋友的不快乐值会增加比当前城市编号高的城市个数(即行进路线符合升序),求p老师的走过的最短路和他女朋友的不快乐值,如果不快乐值为0输出 “ orz”
样例
5
1 2 2
1 3 2
2 4 3
3 5 3
4 5 4
输出
5
lbj is so handsome
代码
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
struct Holder{
int to,next,w;
}e[1000005];
int head[1000005],n,vis[1000005],d[1000005],pre[1000005],path[1000005],t[1000005],c[1000005],cnt2=1,ans=0,N=0;
int cnt=1;
void Add(int u,int v,int w){
e[cnt].to=v;
e[cnt].w=w;
e[cnt].next=head[u];
head[u]=cnt++;
}
int Lowbit(int x){
return x&(-x);
}
void Update(int x){
while(x<=n){
c[x]++;
x+=Lowbit(x);
}
}
int Ask(int x){
int sum=0;
while(x>0){
sum+=c[x];
x-=Lowbit(x);
}
return sum;
}
void Initialize(){
memset(head,0,sizeof head);
memset(vis,0,sizeof(vis));
memset(d,127,sizeof d);
memset(pre,0,sizeof pre);
memset(c,0,sizeof c);
}
int Spfa(){
queue<int> Q;
Q.push(1);vis[1]=1;d[1]=0;
while(!Q.empty()){
int now=Q.front();Q.pop();vis[now]=1;
for(int i=head[now];i;i=e[i].next){
int v=e[i].to;
if(d[v]>e[now].w+d[now]){
d[v]=e[now].w+d[now];
if(!vis[v]){
Q.push(v);
pre[v]=now;
}
}
}
}
}
void GetPre(int x){
if(pre[x]==0)return;
GetPre(pre[x]);
path[++cnt2]=x;
}
int main(){
Initialize();
freopen("ptravell10.in","r",stdin);
freopen("ptravell10.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++){
int u,v,w;
cin>>u>>v>>w;
Add(u,v,w);
}
Spfa();
if(d[n]>=10000){
cout<<"-1"<<endl;
return 0;
}else{
cout<<d[n]<<endl;
}
int x=pre[n];
path[cnt2]=1;
GetPre(n);
N=cnt2;
for(int i=1;i<=cnt2;i++){
Update(path[i]);
ans+=i-Ask(path[i]);
}
if(ans==0){
cout<<"orz"<<endl;
}else{
cout<<ans<<endl;
}
}