您的位置:首页 > 其它

JZOJ.5279【NOIP2017模拟8.15】香港记者

2017-08-15 22:40 309 查看

Description

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<ctime>
#define N 200002
using namespace std;
struct data{
int next,to;
long long power;
}line[N*2];
int team[N*2],head[N*2],visit
,n,m,num,sign
,pre
,qwq
,qaq,cnt;
long long dis
;
void add(int v,int u,int w){
num++;
line[num].next=head[u];
line[num].to=v;
line[num].power=(long long)w;
head[u]=num;
}
bool QAQ(int p,int n){
int x=p,y=n;
while (sign[x]==sign[y]&&x!=0&&y!=0){
x=pre[x];
y=pre[y];
}
if (sign[x]<sign[y]) return false;
return true;
}
void SPFA(){
pre
=0;
int l=0,r=1,v=0,u=0;
memset(visit,false,sizeof(visit));
memset(dis,127,sizeof(dis));
team[r]=n;
dis
=0;
visit
=true;
while (l<r){
u=team[++l];
for (int i=head[u];i;i=line[i].next){
v=line[i].to;
if (dis[u]+line[i].power<dis[v]){
if (!visit[v]){
visit[v]=true;
team[++r]=v;
}
pre[v]=u;
dis[v]=dis[u]+line[i].power;
}
else if (dis[u]+line[i].power==dis[v])
if (QAQ(pre[v],u)) pre[v]=u;
}
visit[u]=false;
}
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&sign[i]);
num=0;
for (int i=1,u,v,w;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
SPFA();
qaq=1;
cnt=0;
while(qaq!=0){
qwq[++cnt]=sign[qaq];
qaq=pre[qaq];
}
printf("%lld\n",dis[1]);
for (int i=1;i<=cnt;i++)
printf("%d ",qwq[i]);
return 0;
}


神奇的代码
其实我们倒着搜遇到距离相等时可以直接比较前驱点的黑框数和当前点的黑框数,直接改,虽然存在反例(如

这个已经反向建边,且点内为黑框眼镜个数,两条路的长度假设相等,这样程序就可能会得出1 2 5 6,这要看读入边的顺序233,不过数据太水没有这情况)

前60%的数据随机这告诉我们最短路很有可能只有一条
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: