zoukankan      html  css  js  c++  java
  • LightOJ 1074

    这一晚,TT 做了个美梦!

    在梦中,TT 的愿望成真了,他成为了喵星的统领!喵星上有 N 个商业城市,编号 1 ~ N,其中 1 号城市是 TT 所在的城市,即首都。

    喵星上共有 M 条有向道路供商业城市相互往来。但是随着喵星商业的日渐繁荣,有些道路变得非常拥挤。正在 TT 为之苦恼之时,他的魔法小猫咪提出了一个解决方案!TT 欣然接受并针对该方案颁布了一项新的政策。

    具体政策如下:对每一个商业城市标记一个正整数,表示其繁荣程度,当每一只喵沿道路从一个商业城市走到另一个商业城市时,TT 都会收取它们(目的地繁荣程度 - 出发地繁荣程度)^ 3 的税。

    TT 打算测试一下这项政策是否合理,因此他想知道从首都出发,走到其他城市至少要交多少的税,如果总金额小于 3 或者无法到达请悄咪咪地打出 ‘?’。

    Input

    第一行输入 T,表明共有 T 组数据。(1 <= T <= 50)

    对于每一组数据,第一行输入 N,表示点的个数。(1 <= N <= 200)

    第二行输入 N 个整数,表示 1 ~ N 点的权值 a[i]。(0 <= a[i] <= 20)

    第三行输入 M,表示有向道路的条数。(0 <= M <= 100000)

    接下来 M 行,每行有两个整数 A B,表示存在一条 A 到 B 的有向道路。

    接下来给出一个整数 Q,表示询问个数。(0 <= Q <= 100000)

    每一次询问给出一个 P,表示求 1 号点到 P 号点的最少税费。

    Output

    每个询问输出一行,如果不可达或税费小于 3 则输出 ‘?’。

    Sample Input

    2
    5
    6 7 8 9 10
    6
    1 2
    2 3
    3 4
    1 5
    5 4
    4 5
    2
    4
    5
    10
    1 2 4 4 5 6 7 8 9 10
    10
    1 2
    2 3
    3 1
    1 4
    4 5
    5 6
    6 7
    7 8
    8 9
    9 10
    2
    3 10

    Sample Output

    Case 1:
    3
    4
    Case 2:
    ?
    ?

    题目大意:

    首先输入一个T 表示有T组测试用例,对于每一组样例,先输入一个n表示点的个数,然后输入 n 个整数,表示w1 - wn 的权值,之后输入一个m,表示有向边的条数,然后输入m行,每行输入a b 表示a b 之间存在一条有向边,需要注意的是,从a到b 的代价是(w[b] - w[a])3 (粗心看成了异或,就离谱)。输入一个Q,表示有Q次询问,对于每一次询问输入一个P,如果不能到达或到达的代价小于3则输出 ‘ ?’ 否则输出到P的最短距离。

    解题思路:

    这道题门道很多,需要注意以下几点。

    1. 因为每个点都有权值,a 到 b 的代价是(w[b] - w[a])3 ,所以建图时应该注意权值问题,然后这里是3次方,第一次看成了异或T.T ,一定要注意
    2. 权值相减有可能出现负数!不能用dijkstra了
    3. 这道题的不能到达有两种情况:第一是不能到达,即距离为inf,第二就是负环负环负环!此时也不能到达,这里要用spfa判负环。
    4. 关于出现负环后的处理,这里用染色法,将出现负环的点的连通分量全部染色,遇到被染色的点直接跳过!
    5. 多组样例,每次不要忘记初始化

    一道很好的题,结合了很多知识点,也有很多坑,调出来收获还是满大的,注意以上的点再套spfa的板子就能AC啦

    Code:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <iomanip>
    #include <sstream>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #define lowbit(x) x & (-x)
    
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> pii;
    
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const int N = 1e6 + 50;
    const int M = 200 + 50;
    
    int h[N], ne[N], e[N], w[N], idx;
    int dis[N], a[N], cnt[N];
    bool vis[N], col[N];
    int T, n, m;
    
    void init()
    {
    	idx = 0;
    	memset(h, -1, sizeof h);
    	memset(cnt, 0, sizeof cnt);
    	memset(col, false, sizeof col);
    }
    
    void add(int a, int b, int c)
    {
    	e[idx] = b;
    	w[idx] = c;
    	ne[idx] = h[a];
    	h[a] = idx++;
    }
    
    void dfs(int u)//将负环所在的连通分量染色
    {
    	col[u] = true;
    
    	for (int i = h[u]; ~i; i = ne[i])
    	{
    		int j = e[i];
    		if (!col[j]) dfs(j);
    	}
    
    	return;
    }
    
    void spfa()
    {
    	memset(vis, false, sizeof vis);
    	memset(dis, 0x3f, sizeof dis);
    	dis[1] = 0;
    
    	queue<int > q;
    	q.push(1);
    	vis[1] = true;
    
    	while (!q.empty())
    	{
    		int t = q.front();
    		q.pop();
    		vis[t] = false;
    		if (col[t]) continue;
    
    		for (int i = h[t]; ~i; i = ne[i])
    		{	
    			int j = e[i];
    			if (dis[t] + w[i] < dis[j])
    			{
    				dis[j] = dis[t] + w[i];
    				cnt[j] = cnt[t] + 1;
    
    				if (!vis[j])
    				{	if (cnt[j] >= n) dfs(j);//不要忘记判负环
    					q.push(j);
    					vis[j] = true;
    				}
    			}
    		}
    	}
    }
    
    int main()
    {
    	int cs = 0;
    	scanf("%d", &T);
    
    	while (T --)
    	{
    		init();//多组初始化一下
    
    		scanf("%d", &n);
    
    		for (int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    
    		scanf("%d", &m);
    
    		while (m --)
    		{
    			int u, v;
    			scanf("%d%d", &u, &v);
    			add(u, v, (a[v] - a[u]) * (a[v] - a[u]) * (a[v] - a[u]));
    		}
    
    		spfa();
    
    		printf("Case %d:
    ", ++cs);
    
    		int q1;
    		scanf("%d", &q1);
    
    		while (q1 --)
    		{
    			int op;
    			scanf("%d", &op);
    
    			if (dis[op] < 3 || dis[op] == inf || col[op]) puts("?");
    			else printf("%d
    ", dis[op]);
    		}
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    Security headers quick reference Learn more about headers that can keep your site safe and quickly look up the most important details.
    Missing dollar riddle
    Where Did the Other Dollar Go, Jeff?
    proteus 与 keil 联调
    cisco router nat
    router dhcp and dns listen
    配置802.1x在交换机的端口验证设置
    ASAv931安装&初始化及ASDM管理
    S5700与Cisco ACS做802.1x认证
    playwright
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294122.html
Copyright © 2011-2022 走看看