zoukankan      html  css  js  c++  java
  • 【NOIP 2013 模拟联考 8】最短路

    简析

    看到 (0le kle10)(k) 非常的小,那么正解可以暴力

    预处理的话,我们考虑先把起点 (s) 和每一个特殊点(k+1) 次最短路。

    然后暴力枚举 (O(n!)) 的顺序,顺序走一次,记录最小值,输出 。

    虽说很简单但还是很考验码力。

    Warning:当 (k=0) 时要特判,否则会出现意想不到的错误。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    using LL=long long;
    const LL N=5e4+5,M=1e5+5;
    struct edge {
    	LL to,nxt,w;
    } e[M];
    LL n,cnt,head[N],dis[N];
    bitset<N> vis;
    void add(LL u,LL v,LL w) {
    	e[++cnt].to=v,e[cnt].w=w,e[cnt].nxt=head[u],head[u]=cnt;
    }
    priority_queue<pair<LL,LL>> q;
    void dijkstra(LL u) {
    	q.push(make_pair(0,u)),dis[u]=0;
    	while(q.size()) {
    		u=q.top().second,q.pop();
    		if(vis[u]) {
    			continue;
    		}
    		vis[u]=1;
    		for(LL i=head[u],v,w; i; i=e[i].nxt) {
    			v=e[i].to,w=e[i].w;
    			if(dis[u]+w<dis[v]) {
    				dis[v]=dis[u]+w;
    				q.push(make_pair(-dis[v],v));
    			}
    		}
    	}
    }
    void dijkstra(LL u,LL *dis) {
    	q.push(make_pair(0,u)),dis[u]=0;
    	while(q.size()) {
    		u=q.top().second,q.pop();
    		if(vis[u]) {
    			continue;
    		}
    		vis[u]=1;
    		for(LL i=head[u],v,w; i; i=e[i].nxt) {
    			v=e[i].to,w=e[i].w;
    			if(dis[u]+w<dis[v]) {
    				dis[v]=dis[u]+w;
    				q.push(make_pair(-dis[v],v));
    			}
    		}
    	}
    }
    LL key[15],ge[15][N],a[15];
    int main() {
    	LL n,m,k,s,t;
    	scanf("%lld %lld %lld %lld %lld",&n,&m,&k,&s,&t);
    	for(LL i=1,u,v,w; i<=m; i++) {
    		scanf("%lld %lld %lld",&u,&v,&w),add(u,v,w);
    	}
    	for(LL i=1; i<=k; i++) {
    		memset(ge[i],0x3f,sizeof(ge[i])),vis=0;
    		scanf("%lld",key+i);
    		if(key[i]==s||key[i]==t) {
    			i--,k--;
    			continue;
    		}
    		dijkstra(key[i],ge[i]),a[i]=i;
    	}
    	memset(dis,0x3f,sizeof(dis)),vis=0,dijkstra(s);
    	LL minn=1e15;
    	do {
    		LL tmp=dis[key[a[1]]];
    		for(LL i=1; i<k; i++) {
    			tmp+=ge[a[i]][key[a[i+1]]];
    		}
    		tmp+=ge[a[k]][t];
    		if(!k) {
    			tmp=dis[t];
    		}
    		minn=min(minn,tmp);
    	} while(next_permutation(a+1,a+k+1));
    	if(minn>=1e12) {
    		puts("-1");
    		return 0;
    	}
    	printf("%lld",minn);
    	return 0;
    }
    

    本文作者:AFewMoon,文章地址:https://www.cnblogs.com/AFewMoon/p/15185206.html

    知识共享许可协议

    本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。

    限于本人水平,如果文章有表述不当之处,还请不吝赐教。

  • 相关阅读:
    20150316--TP-01
    20150314--TP-02
    20150314--TP-01
    20150313+微信-全
    表单/iframe与video标签
    图像/超链接标签
    HTML列表与表格
    JAVA新的一天
    MySQL常用函数
    php基础--来自网页转载
  • 原文地址:https://www.cnblogs.com/Sam2007/p/15185206.html
Copyright © 2011-2022 走看看