地址:http://blog.csdn.net/wyfcyx_forever/article/details/45875055
#include<cstdio> #include<cstring> #include<cctype> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define mp make_pair #define pb push_back #define inf 0x3f3f3f3f #define N 10010 int n,m,K; typedef long long ll; typedef pair<int,int> pii; struct SegmentTree { pii s[32768]; int M; inline void init(int _siz) { for(M=1; M<(_siz+2); M<<=1); for(int i=0; i<(M<<1); ++i) s[i]=mp(inf,0); } inline void modify(int x,int y) { for(s[x+M]=mp(y,x),(x+=M)>>=1; x; x>>=1) s[x]=min(s[x<<1],s[x<<1^1]); } inline int getid() { return s[1].second; } } Seg; struct Graph { static const int V=N; static const int E=100010; int head[V],next[E],end[E],len[E],ind; inline void reset() { ind=0; memset(head,0,sizeof head); } inline void addedge(int a,int b,int c) { int q=++ind; end[q]=b,next[q]=head[a]; head[a]=q,len[q++]=c; } } g,_g,tree; int d[N]; inline void dijkstra(int s,Graph&g) { memset(d,0x3f,sizeof d); Seg.init(n); d[s]=0; Seg.modify(s,0); for(int i=1; i<=n; ++i) { int x=Seg.getid(); for(int j=g.head[x]; j; j=g.next[j]) { if(d[g.end[j]]>d[x]+g.len[j]) { d[g.end[j]]=d[x]+g.len[j]; Seg.modify(g.end[j],d[g.end[j]]); } } Seg.modify(x,inf); } } int pa[N]; struct Node { Node*l,*r; int v,tail,dist; Node():dist(0) {} } mempool[1000010],*P=mempool,Tnull,*null=&Tnull; inline Node*newnode(int _v,int _tail) { P->l=P->r=null; P->v=_v; P->tail=_tail; P->dist=1; return P++; } inline void copy(Node*&p,Node*q) { if(q==null) p=null; else *p=*q; } inline Node*merge(Node*p,Node*q) { Node*s=P++; if(p==null||q==null) { copy(s,p==null?q:p); return s; } if(p->v>q->v) swap(p,q); copy(s,p); s->r=merge(p->r,q); if(s->l->dist<s->r->dist) swap(s->l,s->r); s->dist=s->r->dist+1; return s; } Node*root[N]; struct State { ll ldist; Node*ledge; State():ldist(0ll),ledge(null) {} State(ll _ldist,Node* _ledge):ldist(_ldist),ledge(_ledge) {} bool operator<(const State&B)const { return ldist>B.ldist; } }; priority_queue<State> Q; bool treeedge[100010]; int main() { cin>>n>>m>>K; int i,j,a,b,c; g.reset(); _g.reset(); for(i=1; i<=m; ++i) { scanf("%d%d%d",&a,&b,&c); g.addedge(a,b,c); _g.addedge(b,a,c); } dijkstra(n,_g); for(i=1; i<n; ++i) for(j=g.head[i]; j; j=g.next[j]) if(d[i]==d[g.end[j]]+g.len[j]) { pa[i]=g.end[j]; treeedge[j]=1; break; } tree.reset(); for(i=1; i<n; ++i) tree.addedge(pa[i],i,0); queue<int>q; q.push(n); Node*p; root[0]=null; while(!q.empty()) { i=q.front(); q.pop(); root[i]=merge(null,root[pa[i]]); for(j=g.head[i]; j; j=g.next[j]) if(!treeedge[j]) { p=newnode(g.len[j]-(d[i]-d[g.end[j]]),g.end[j]); root[i]=merge(root[i],p); } for(j=tree.head[i]; j; j=tree.next[j]) q.push(tree.end[j]); } if(K==1) cout<<d[1]<<endl; else { --K; Q.push(State(d[1]+root[1]->v,root[1])); State tmp; ll ldist; Node*ledge; for(int i=1; i<=K; ++i) { tmp=Q.top(); Q.pop(); ldist=tmp.ldist; ledge=tmp.ledge; if(i==K) { cout<<ldist<<endl; break; } Q.push(State(ldist+root[ledge->tail]->v,root[ledge->tail])); if(ledge->l!=null) Q.push(State(ldist-ledge->v+ledge->l->v,ledge->l)); if(ledge->r!=null) Q.push(State(ldist-ledge->v+ledge->r->v,ledge->r)); } } return 0; }