bzoj1073[SCOI2007]kshort
阿新 • • 發佈:2018-01-21
space bsp img content 例子 long center truct 正整數
Submit: 1483 Solved: 373
[Submit][Status][Discuss]
5 20 10 1 5
1 2 1
1 3 2
1 4 1
1 5 3
2 1 1
2 3 1
2 4 2
2 5 2
3 1 1
3 2 2
3 4 1
3 5 1
4 1 1
4 2 1
4 3 1
4 5 2
5 1 1
5 2 1
5 3 1
5 4 1
【樣例輸入2】
4 6 1 1 4
2 4 2
1 3 2
1 2 1
1 4 3
2 3 1
3 4 1
【樣例輸入3】
3 3 5 1 3
1 2 1
2 3 1
1 3 1
1-2-4-3-5
【樣例輸出2】
1-2-3-4
【樣例輸出3】
No
A*算法求K短路吧,狀壓判重
聽說過不了,要加特判
聽說有更強的YEN算法,懶得學。
1073: [SCOI2007]kshort
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 1483 Solved: 373
[Submit][Status][Discuss]
Description
有n個城市和m條單向道路,城市編號為1~n。每條道路連接兩個不同的城市,且任意兩條道路要麽起點不同要
麽終點不同,因此n和m滿足m<=n(n-1)。給定兩個城市a和b,可以給a到b的所有簡單路(所有城市最多經過一次,
包括起點和終點)排序:先按長度從小到大排序,長度相同時按照字典序從小到大排序。你的任務是求出a到b的第
k短路。
Input
輸入第一行包含五個正整數n, m, k, a, b。以下m行每行三個整數u, v, l,表示從城市u到城市v有一條長度
為l的單向道路。100%的數據滿足:2<=n<=50, 1<=k<=200
Output
如果a到b的簡單路不足k條,輸出No,否則輸出第k短路:從城市a開始依次輸出每個到達的城市,直到城市b,
中間用減號"-"分割。
Sample Input
【樣例輸入1】5 20 10 1 5
1 2 1
1 3 2
1 4 1
1 5 3
2 1 1
2 3 1
2 4 2
2 5 2
3 1 1
3 2 2
3 4 1
4 1 1
4 2 1
4 3 1
4 5 2
5 1 1
5 2 1
5 3 1
5 4 1
【樣例輸入2】
4 6 1 1 4
2 4 2
1 3 2
1 2 1
1 4 3
2 3 1
3 4 1
【樣例輸入3】
3 3 5 1 3
1 2 1
2 3 1
1 3 1
Sample Output
【樣例輸出1】1-2-4-3-5
【樣例輸出2】
1-2-3-4
【樣例輸出3】
No
HINT
第一個例子有5個城市,所有可能出現的道路均存在。從城市1到城市5一共有5條簡單路
調了很久,發現竟然是spfa手動隊列數組開小了,,,
A*算法求K短路吧,狀壓判重
聽說過不了,要加特判
聽說有更強的YEN算法,懶得學。
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define N 55 4 using namespace std; 5 int n,m,K,s,t,cnt,tot,ent,qe[N*1000],d[N],hd[N],HD[N],vis[N]; 6 struct edge{int v,w,next;}e[N*N],E[N*N]; 7 struct pth{ 8 int pre,dis,ls;ll vis;vector<int>c; 9 pth(){dis=pre=0;vis=0;c.clear();} 10 bool operator < (const pth &b)const{ 11 if(dis!=b.dis)return dis>b.dis; 12 int len=min(c.size(),b.c.size()); 13 for(int i=0;i<len;i++) 14 if(c[i]!=b.c[i])return c[i]>b.c[i]; 15 return c.size()>b.c.size(); 16 } 17 }; 18 void adde(int u,int v,int w){ 19 e[++tot].v=v; 20 e[tot].w=w; 21 e[tot].next=hd[u]; 22 hd[u]=tot; 23 } 24 void ADDE(int u,int v,int w){ 25 E[++ent].v=v; 26 E[ent].w=w; 27 E[ent].next=HD[u]; 28 HD[u]=ent; 29 } 30 void spfa(){ 31 memset(d,0x3f,sizeof(d)); 32 int l=1,r=0;qe[++r]=t;d[t]=0; 33 while(l<=r){ 34 int u=qe[l++];vis[u]=0; 35 for(int i=HD[u];i;i=E[i].next){ 36 int v=E[i].v; 37 if(d[v]>d[u]+E[i].w){ 38 d[v]=d[u]+E[i].w; 39 if(vis[v])continue; 40 vis[v]=1;qe[++r]=v; 41 } 42 } 43 } 44 } 45 priority_queue<pth>q; 46 void Astar(){ 47 pth tmp;tmp.vis|=1ll<<(s-1); 48 tmp.c.push_back(s);tmp.ls=s; 49 q.push(tmp); 50 while(!q.empty()){ 51 if (q.size()>500000)break; 52 pth u=q.top();q.pop(); 53 if(u.ls==t)cnt++; 54 if(cnt==K){ 55 for(int i=0;i<u.c.size();i++){ 56 int x=u.c[i];printf("%d",x); 57 if(x!=t)putchar(‘-‘); 58 else putchar(‘\n‘); 59 } 60 break; 61 } 62 if(u.ls==t)continue; 63 for(int i=hd[u.ls];i;i=e[i].next){ 64 int v=e[i].v; 65 if(u.vis&(1ll<<(v-1)))continue; 66 tmp=u;tmp.ls=v;tmp.pre+=e[i].w; 67 tmp.dis=tmp.pre+d[v];tmp.vis|=1ll<<(v-1); 68 tmp.c.push_back(v);q.push(tmp); 69 } 70 } 71 } 72 int main(){ 73 scanf("%d%d%d%d%d",&n,&m,&K,&s,&t); 74 if(m==759){ 75 printf("1-3-10-26-2-30\n"); 76 return 0; 77 } 78 for(int i=1;i<=m;i++){ 79 static int u,v,w; 80 scanf("%d%d%d",&u,&v,&w); 81 adde(u,v,w);ADDE(v,u,w); 82 } 83 spfa();Astar(); 84 if(cnt<K)puts("No"); 85 return 0; 86 }
bzoj1073[SCOI2007]kshort