您的位置:首页 > 其它

WUST OJ:2058: 划水的魅力(spfa)

2017-09-20 23:42 274 查看


2058: 划水的魅力

Time Limit: 1 Sec  Memory Limit: 512 MB  
64bit IO Format: %lld
Submitted: 40  Accepted: 6


Description

这个世界有n个城市(城市编号从1到n),人们修了m条路来连接各个城市,但这个世界很奇怪,有的路是单向的,有的路是双向的。
lala住在编号为citya的城市,其中有nn个划水城市,lala很想去划水,
但lala不知道去哪个划水城市走的路程才最短,于是他向你求助,相信聪明的你一定能帮lala找到最短路径!


Input

多组测试数据,每组测试数据输入如下:
第1行两个整数:n(1<n<6000),m(0<m<min(n(n-1)/2,10n) )分别表示城市个数和路的条数。
第2-m+1行,每行四个整数:a(0<a<=n),b(0<b<=n),c(0<=c<=2),d(0<d<10000)表示城市a到城市b之间有条长为d的路,(c=0表示路是双向的,c=1表示路是只能从城市a走到城市b,c=2表示只能从城市b走到城市a),
保证与每个城市相连点的个数不超过20(保证不存在重边和自环)。
第m+2行两个整数:citya(0<citya<=n),nn(0<nn<n)分表示lala所在的城市,和lala想去划水的城市个数。
第m+3行nn个整数:city[1]~city[nn]表示lala想去划水的城市。


Output

每组测
4000
试数据,输出如下:
如果能走到其中一个划水城市,找出距离lala路程最短的划水城市(保证这种情况下只存在一个合法解),并输出两部分,第一部分输出路径(10城市个输出一行,"->"不放在行尾),第二部分输出一行路程。
如果都不能走到,输出一行"Let me think again"(输出不含引号)。


Sample Input 

4 5

1 3 0 11

1 2 2 5

2 3 2 10

3 4 1 2

2 4 0 3

1 1

2

5 6

1 3 0 11

1 2 2 5

2 3 2 10

3 4 1 2

2 4 0 3

3 5 2 6

2 1

5


Sample Output

1->3->4->2

16

Let me think again 

思路:spfa求最短路。有坑!!题目说每10个城市输出一行,其实第一行只输出9个城市,其余每行输出10个城市。

#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<cstdio>
using namespace std;
const int MAX=7000;
const int INF=1e9+7;
int g[MAX];
stack<int>A;
struct lenka
{
int d,u;
bool operator<(const lenka& ch)const{return d>ch.d;}
};
struct Edge
{
int from,to,dist;
};
struct DD
{
int n,m;
vector<Edge>ed;
vector<int>G[MAX];
int done[MAX];
int d[MAX];
int p[MAX]; //记录路径
void init(int n)
{
memset(p,0,sizeof p);
this->n=n;
for(int i=0;i<=n;i++)G[i].clear();
ed.clear();
}
void add(int from,int to,int dist)
{
ed.push_back((Edge){from,to,dist});
m=ed.size();
G[from].push_back(m-1);
}
void Dijkstra(int s)
{
priority_queue<lenka>q;
for(int i=0;i<=n;i++)d[i]=INF;
d[s]=0;
memset(done,0,sizeof done);
q.push((lenka){0,s});
while(!q.empty())
{
lenka now=q.top();q.pop();
int u=now.u;
if(done[u])continue;
done[u]=1;
for(int i=0;i<G[u].size();i++)
{
Edge& e=ed[G[u][i]];
if(d[e.to]>d[u]+e.dist)
{
d[e.to]=d[u]+e.dist;
p[e.to]=e.from;
q.push((lenka){d[e.to],e.to});
}
}
}
}
}ans;
void dfs(int x)
{
if(x==0)return;
A.push(x);
dfs(ans.p[x]);
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
ans.init(n);
for(int i=0;i<m;i++)
{
int x,y,z,pp;
scanf("%d%d%d%d",&x,&y,&z,&pp);
if(z==0)
{
ans.add(x,y,pp);
ans.add(y,x,pp);
}
else if(z==1)ans.add(x,y,pp);
else ans.add(y,x,pp);
}
int st,T;
scanf("%d%d",&st,&T);
ans.Dijkstra(st);
for(int i=0;i<T;i++)scanf("%d",&g[i]);
int y=INF,x;
for(int i=0;i<T;i++)
{
if(y>ans.d[g[i]])
{
y=ans.d[g[i]];
x=g[i];
}
}
if(y!=INF)
{
A.push(x);
dfs(ans.p[x]);
for(int i=1;i<=9;i++)
{
if(!A.empty())printf("%d",A.top()),A.pop();
if(!A.empty()&&i<9)printf("->");
}
printf("\n");
while(!A.empty())
{
printf("->");
for(int i=1;i<=10;i++)
{
if(!A.empty())printf("%d",A.top()),A.pop();
if(!A.empty()&&i<10)printf("->");
}
printf("\n");
}
printf("%d\n",y);
}
else puts("Let me think again");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: