zoukankan      html  css  js  c++  java
  • POJ 3268 Silver Cow Party (dijkstra)

    题意:给出一个单向带权图和一个点s,求点u,u到s的最短路径和s到u的最短路径之和最大。

    思路:

    对于s到任意点的最短路,直接dijkstra可以求出。

    对于任意点到s的最短路,将所有边反向然后求一次最短路。容易证明,求出的s到任意点v的最短路s-->v就是原来没有反向的图的v-->s的最短路。

    所以先求一次dijkstra,保存此次的结果,然后把所有的边反向,权值不变,再求一次dijkstra,将两次结果加起来,计算它们之中的最大值。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 1010
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int n, m;
    int value[maxn][maxn];
    int dis[maxn];
    bool vis[maxn];
    int dis2[maxn];
    
    void dijkstra(int s) 
    {
    	memset(vis, false, sizeof(vis));
    	for (int i = 1; i <= n; i++) dis[i] = inf;
    	dis[s] = 0;
    
    	while(true) 
    	{
    		int v = -1;
    		for (int j = 1; j <= n; j++) 
    		{
    			if (!vis[j] && (v == -1 || dis[j]< dis[v])) v = j;
    		}
    		if (v == -1) break;
    		vis[v] = true;
    		for (int j = 1; j <= n; j++) 
    		{
    			if (dis[j] > dis[v] + value[v][j]) 
    			{
    				dis[j] = dis[v] + value[v][j];
    			}
    		}
    	}
    }
    
    void dijkstra2(int s) 
    {
    	memset(vis, false, sizeof(vis));
    	for (int i = 1; i <= n; i++) dis2[i] = inf;
    	dis2[s] = 0;
    
    	while (true)
    	{
    		int v = -1;
    		for (int j = 1; j <= n; j++)
    		{
    			if (!vis[j] && (v == -1 || dis2[j]< dis2[v])) v = j;
    		}
    		if (v == -1) break;
    		vis[v] = true;
    		for (int j = 1; j <= n; j++)
    		{
    			if (dis2[j] > dis2[v] + value[j][v])
    			{
    				dis2[j] = dis2[v] + value[j][v];
    			}
    		}
    	}
    }
    
    int main()
    {
    	int aim;
    	while (scanf("%d %d %d", &n, &m, &aim) != EOF)
    	{
    		for (int i = 1; i <= n; i++)
    		for (int j = 1; j <= n; j++)
    			value[i][j] = inf;
    		while (m--)
    		{
    			int u, v, w; cin >> u >> v >> w;
    			if (w < value[u][v]) value[u][v] = w;
    		}
    
    		dijkstra(aim);
    		dijkstra2(aim);
    
    		int ans = 0;
    		for (int i = 1; i <= n; i++) 
    			if (dis[i] != inf && dis2[i] != inf)
    				ans = max(ans, dis[i] + dis2[i]);
    
    		printf("%d
    ", ans);
    	}
    
    	return 0;
    }

    注:这里的dijkstra用的是一般方法,复杂度(V^2),也可以用最小堆(优先队列)处理,复杂度(E log(V))

  • 相关阅读:
    cf Round #764(Div. 3)
    查看w3wp.exe 进程
    CAML语法 Query写法
    InfoPaht 复选框
    性能工具MiniProfiler在Asp.Net WebForm跟踪EntityFramework
    CAML基础语法
    Moss 本机无法访问(转)
    STSADM 不是内部或外部命令
    spBodyOnLoadFunctionNames
    关于代码调用SSP获取UserProfile出错的解决方案(转)
  • 原文地址:https://www.cnblogs.com/demian/p/7389878.html
Copyright © 2011-2022 走看看