codeforces gym 100753e 简单最短路+恶心的超内存

Every day you drive to work using the same roads as it is the shortest way. This is efficient, but over time you have grown increasingly bored of seeing the same buildings and junctions every day. So you decide to look for different routes. Of course you do not want to sacrifice time, so the new way should be as short as the old one. Is there another way that differs from the old one in at least one street?

Input Format

The first line of the input starts with three integers NN MM and KK, where NN is the number of junctions and MM is the number of streets in your city, and KK is the number of junctions you pass everyday (1 \le K \le N \le 10000, 0 \le M \le 1000000)(1KN10000,0M1000000).

The next line contains KK integers, the (11-based) indices of the junctions you pass every day. The first integer in this line will always be 11, the last integer will always be NN. There is a shortest path from 11 to NN along the KKjunctions given.

MM lines follow. The ii-th of those lines contains three integers a_iai b_ibi c_ici and describes a street from junction a_iai to junction b_ibi of length c_ici (1 \le a_i,b_i \le N, 1 \le c_i \le 10000)(1ai,biN,1ci10000). Streets are always undirected.

Note that there may be multiple streets connecting the same pair of junctions. The shortest path given uses for every pair of successive junctions aa and bb a street of minimal length between aa and bb.

Output Format

Print one line of output containing "yes" if there is another way you can take without losing time, "no"otherwise.

样例输入1
3 3 3
1 2 3
1 2 1
2 3 2
1 3 3
样例输出1
yes
样例输入2
4 5 2
1 4
1 2 2
2 4 1
1 3 1
3 4 2
1 4 2
样例输出2
no
代码:
#include<bits/stdc++.h>

using namespace std;
const int N =1e4+5;
const int M =2010000;
const int inf =0x3f3f3f3f;
const int mod=1e9+7;
typedef pair<int,int > pii;
struct node
{
	int to;
	int next;
	int w;
}edge[M];

int head[N],tot;

void init()
{
	memset(head,-1,sizeof(head));
	tot=0;
}

void add(int u,int v,int w)
{
	edge[++tot].to=v; edge[tot].w=w; edge[tot].next=head[u];  head[u]=tot;
	return ;
}


int dis[N];
bool vis[N];
int pcnt[N];
int n,m,k;
priority_queue<pii,vector<pii>, greater<pii> >q;


void dij()
{
	for(int i=0;i<=n;i++){
		dis[i]=inf;  vis[i]=0;  pcnt[i]=0;
	}
	dis[1]=0; vis[1]=1; pcnt[1]=1;
	while(!q.empty()) q.pop();
	q.push(pii(0,1));

	int u,v,w;
	pii tmp;
    int val;

	while(!q.empty()){
		tmp=q.top();  q.pop();
		u=tmp.second;
		if(tmp.first>dis[u]) continue;
		vis[u]=1;

		for(int i=head[u];i!=-1;i=edge[i].next){
			v=edge[i].to;
			val=edge[i].w;
			//if(vis[v]) continue;  //因为要判断相等的情况,所以这里不能判断是否访问过。

			if(dis[v]>dis[u]+val){
				dis[v]=dis[u]+val;
				pcnt[v]=pcnt[u];
				q.push(make_pair(dis[v],v));
			}
			else if(dis[v]==dis[u]+val){
				pcnt[v]=(pcnt[v]+pcnt[u])%mod;
				//q.push(make_pair(dis[v],v));  这里加上的话就会超内存。 增加无用的操作,但使得堆变大。
			}
		}
	}

	if(pcnt[n]>1){
		cout<<"yes"<<endl;
		return ;
	}
	cout<<"no"<<endl;
	return ;
}

int main()
{
	scanf("%d %d %d",&n,&m,&k);
	int x;
	for(int i=1;i<=k;i++) scanf("%d",&x);
	int u,v,w;
	init();
	for(int i=1;i<=m;i++){
		scanf("%d %d %d",&u,&v,&w);
		add(u,v,w);
		add(v,u,w);
	}

	dij();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值