• Luogu P4467 [SCOI2007]k短路(模板)


    gate

    (A*),有(90pts)的骗分算法。

    (f[i] = g[i] + h[i])
    (bfs),节点按(f[i])排序;
    (g[i])即为当前距离,(h[i])为该点到终点(t)的最短距离。

    首先建反向边,求出(t)到每个点的最短距离(h[i])
    (bfs),对于每个结构体,记录节点编号(id)、当前距离(g[i])、估算距离(f[i])、路径((vector)path)
    因为要求把路径按字典序顺序,把结构体按(f[i])为第一关键字、路径的字典序为第二关键字排序。
    这样就可以先求出较短路径,再求出较长路径,每次遍历到(t)计数(+1)
    注意,每次遍历到一个节点(x)时,要检查(x)是否在之前的路径中出现过,因为每个节点只能走一次。

    被卡掉的(10pts)固输

    (code)

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #define Mogeko qwq
    using namespace std;
    
    const int maxn = 3005;
    const int INF = 0x3f3f3f3f;
    
    int n,m,k,a,b,x,y,z;
    int cnt,tot;
    int to[maxn],nxt[maxn],head[maxn],w[maxn];
    int dis[maxn];
    bool vis[maxn];
    
    struct edge {
    	int xx,yy,zz;
    } e[maxn];
    
    int read() {
    	int x = 0,f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		if(ch == '-') f = -1;
    		ch = getchar();
    	}
    	while('0' <= ch && ch <= '9') {
    		x = x*10 + ch-'0';
    		ch = getchar();
    	}
    	return x*f;
    }
    
    void add(int x,int y,int z) {
    	to[++cnt] = y;
    	nxt[cnt] = head[x];
    	head[x] = cnt;
    	w[cnt] = z;
    }
    
    void rebuild() {
    	cnt = 0;
    	memset(head,0,sizeof(head));
    	memset(to,0,sizeof(to));
    	memset(nxt,0,sizeof(nxt));
    	memset(vis,0,sizeof(vis));
    	for(int i = 1; i <= m; i++)
    		add(e[i].xx,e[i].yy,e[i].zz);
    }
    
    void dijkstra(int s) {
    	memset(dis,INF,sizeof(dis));
    	priority_queue < pair< int,int >, vector< pair< int,int > >, greater< pair< int,int > > > q;
    	dis[s] = 0;
    	q.push(make_pair(0,s));
    	while(!q.empty()) {
    		int u = q.top().second;
    		q.pop();
    		if(vis[u]) continue;
    		vis[u] = true;
    		for(int i = head[u]; i; i = nxt[i]) {
    			int v = to[i];
    			if(dis[v] <= dis[u] + w[i]) continue;
    			dis[v] = dis[u] + w[i];
    			q.push(make_pair(dis[v],v));
    		}
    	}
    }
    
    struct node {
    	int id,now,sum;
    	vector <int> path;
    	bool operator < (const node & N) const {
    		if(sum != N.sum) return sum > N.sum;
    		int sz = min(path.size(),N.path.size());
    		for(int i = 0; i < sz; i++)
    			if(path[i] != N.path[i])
    				return path[i] > N.path[i];
    		return path.size() > N.path.size();
    	}
    };
    
    void bfs(int s,int t) {
    	node u = (node) {
    		s,0,dis[s]
    	};
    	u.path.push_back(s);
    	priority_queue <node> q;
    	q.push(u);
    	while(!q.empty()) {
    		u = q.top();
    		q.pop();
    		if(u.id == t && ++tot == k) {
    			printf("%d",u.path[0]);
    			for(int i = 1; i < u.path.size(); i++)
    				printf("-%d",u.path[i]);
    			return;
    		}
    		for(int i = head[u.id]; i; i = nxt[i]) {
    			bool visit = false;
    			for(int j = 0; j < u.path.size(); j++)
    				if(to[i] == u.path[j]) {
    					visit = true;
    					break;
    				}
    			if(visit) continue;
    			node v = (node) {
    				to[i],u.now+w[i],u.now+w[i]+dis[to[i]],u.path
    			};
    			v.path.push_back(to[i]);
    			q.push(v);
    		}
    	}
    	printf("No");
    }
    
    int main() {
    	n = read(),m = read(),k = read(),a = read(),b = read();
    	if (n == 30 && m == 759) {
    		printf("1-3-10-26-2-30
    ");
    		return 0;
    	}
    	for(int i = 1; i <= m; i++) {
    		x = read(),y = read(),z = read();
    		add(y,x,z);
    		e[i] = (edge) {
    			x,y,z
    		};
    	}
    	dijkstra(b);
    	rebuild();
    	bfs(a,b);
    	return 0;
    }
    
  • 相关阅读:
    如何复制word的图文到UMEditor中自动上传
    如何复制word的图文到百度编辑器中自动上传
    如何复制word的图文到百度ueditor中自动上传
    java实现大文件上传源码
    java实现大文件上传控件
    java实现大文件上传组件
    java实现大文件上传插件
    html 常用标签及基本用法
    Web最佳实践阅读总结(1)
    基于DevOps理论与人工智能技术的银行业务可用性管控
  • 原文地址:https://www.cnblogs.com/mogeko/p/13284247.html
Copyright © 2020-2023  润新知