zoukankan      html  css  js  c++  java
  • SPFA(负环) LightOJ 1074 Extended Traffic

    题目传送门

    题意:收过路费.如果最后的收费小于3或不能达到,输出'?'.否则输出到n点最小的过路费

    分析:关键权值可为负,如果碰到负环是,小于3的约束条件不够,那么在得知有负环时,把这个环的点都标记下,DFS实现.

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    const int N = 2e2 + 5;
    const int E = 1e4 + 5;
    const int INF = 0x3f3f3f3f;
    struct Edge	{
    	int v, w, nex;
    	Edge()	{}
    	Edge(int v, int w, int nex) : v (v), w (w), nex (nex) {}
    	bool operator < (const Edge &r) const	{
    		return w > r.w;
    	}
    }edge[E];
    int head[N];
    int d[N];
    int cnt[N];
    int a[N];
    bool vis[N], vis2[N];
    int n, m, e;
    
    void init()	{
    	memset (head, -1, sizeof (head));
    	e = 0;
    }
    
    void add_edge(int u, int v, int w)	{
    	edge[e] = Edge (v, w, head[u]);
    	head[u] = e++;
    }
    
    void DFS(int u)	{
    	vis2[u] = true;
    	for (int i=head[u]; ~i; i=edge[i].nex)	{
    		int v = edge[i].v;
    		if (!vis2[v])	{
    			DFS (v);
    		}
    	}
    }
    
    void SPFA(int s)	{
    	memset (cnt, 0, sizeof (cnt));
    	memset (vis, false, sizeof (vis));
    	memset (vis2, false, sizeof (vis2));
    	memset (d, INF, sizeof (d));
    	d[s] = 0;	cnt[s] = 0;	vis[s] = true;
    	queue<int> que;	que.push (s);
    	while (!que.empty ())	{
    		int u = que.front ();	que.pop ();
    		vis[u] = false;
    		for (int i=head[u]; ~i; i=edge[i].nex)	{
    			int v = edge[i].v, w = edge[i].w;
    			if (vis2[v])	continue;
    			if (d[v] > d[u] + w)	{
    				d[v] = d[u] + w;
    				if (!vis[v])	{
    					vis[v] = true;	que.push (v);
    					if (++cnt[v] > n)	{
    						DFS (v);
    					}
    				}
    			}
    		}
    	}
    }
    
    int cal(int i, int j)	{
    	int ret = a[i] - a[j];
    	ret = ret * ret * ret;
    	return ret;
    }
    
    int main(void)	{
    	int T, cas = 0;	scanf ("%d", &T);
    	while (T--)	{
    		init ();
    		scanf ("%d", &n);
    		for (int i=1; i<=n; ++i)	{
    			scanf ("%d", &a[i]);
    		}
    		scanf ("%d", &m);
    		for (int u, v, i=1; i<=m; ++i)	{
    			scanf ("%d%d", &u, &v);
    			add_edge (u, v, cal (v, u));
    		}
    		SPFA (1);
    		int q;	scanf ("%d", &q);
    		printf ("Case %d:
    ", ++cas);
    		while (q--)	{
    			int x;	scanf ("%d", &x);
    			if (d[x] == INF || d[x] < 3 || vis2[x])	puts ("?");
    			else	printf ("%d
    ", d[x]);
    		}
    	}
    
    	return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    POJ3687拓扑排序+贪心
    POJ3687拓扑排序+贪心
    POJ3614奶牛晒阳光DINIC或者贪心
    POJ3614奶牛晒阳光DINIC或者贪心
    POJ3070矩阵快速幂简单题
    POJ3070矩阵快速幂简单题
    POJ3040给奶牛发工资
    POJ3040给奶牛发工资
    #Leetcode# 78. Subsets
    #Leetcode# 89. Gray Code
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5008528.html
Copyright © 2011-2022 走看看