zoukankan      html  css  js  c++  java
  • P5590 赛车游戏

    题目描述

    R 君和小伙伴打算一起玩赛车。但他们被老司机 mocania 骗去了秋名山。

    秋名山上有 n 个点和 m 条边,R 君和他的小伙伴要从点 1 出发开往点 n,每条边都有一个初始的方向。老司机 mocania 拿到了秋名山的地图但却不知道每条路有多长。显然,为了赛车游戏的公平,每条 11 到 nn 的路径应当是等长的。mocania 想,我就随便给边表上一个 1...9 的长度,反正傻傻的 R 君也看不出来。

    可 mocania 的数学不大好,不知道怎么给边标长度,只能跑来请教你这个 OI 高手了。

    输入格式

    第一行两个整数 n,m。

    接下来 mm 行,每行两个整数 u,v,表示一条从 u 到 v 的有向边。

    输出格式

    如果无解或者不存在 1 到 n 的路径直接输出一个 -1。

    如果有解第一行输出两个数 n,m,和输入文件中给出的相同。

    借下来 m 行,每行三个整数 u,v,w,表示把从 u 到 v 的路径的长度设置为 w,其中 ww 是一个 1...9 的整数。要求所有边的出现顺序和题目中给出的相同。

    输入输出样例

    输入 #1复制

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

    输出 #1复制

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

    说明/提示

    数据范围

    本题启用 Special Judge 和 Subtask。

    Subtask #1:30% 的分数,n <= 10, m <= 20
    Subtask #2:60% 的分数,n <= 100, m <= 200
    Subtask #3:100% 的分数,n <= 1000, m <= 2000

    保证数据中不会出现重边,自环。

    这个是luogu10月月赛的题,当时被虐到只会puts("0")
    现在。。。只会puts("-1")...

    差分约束
    题目要求每个边的长度都在1到9之间。也就是说对于一个边(u ,v) 有 1 <= dis[v] - dis[u] <= 9
    我个人喜欢大连小,所以 连边(v , u , 1) , (u , v , -9)
    注意 开始时dis不能赋成0,有负数。。。
    还有要把不在1到n路径上的边忽略,不给他们连差分约束的边。。
    这个可以用一正一反两边dfs搞定。。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    typedef long long LL;
    const int N = 1010;
    inline int read()
    {
        register int x = 0 , f = 0; register char c = getchar();
        while(c < '0' || c > '9') f |= c == '-' , c = getchar();
        while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0' , c = getchar();
        return f ? -x : x;
    }
    int n , m , cnt;
    int head[N] , eu[N<<1] , ev[N<<1] , vis[N] , t[N] , dis[N] , bo[N] , bo1[N] , bo2[N];
    struct edge{ int v , nex , c; }e[N<<2];
    inline void add(int u , int v , int c) { e[++cnt].v = v; e[cnt].nex = head[u]; e[cnt].c = c; head[u] = cnt; return ; }
    
    void dfs1(int x)
    {
    	bo1[x] = 1;
    	for(int i = head[x]; i ; i = e[i].nex) if(i & 1) // 求出1能到那些点 
    		if(!bo1[e[i].v]) dfs1(e[i].v);
    	return ;
    }
    
    void dfs2(int x)
    {
    	bo2[x] = 1;
    	for(int i = head[x] ; i ; i = e[i].nex) if(!(i & 1)) // 求出那些点能到n
    		if(!bo2[e[i].v]) dfs2(e[i].v);
    	return ;
    }
    
    queue<int> q;
    bool SPFA()
    {
    	for(int i = 2 ; i <= n ; ++i) dis[i] = -1e8; q.push(1);
    	while(q.size())
    	{
    		int x = q.front(); q.pop(); vis[x] = 0; if((++t[x]) >= n) return false; // 此处是 >= n , .. 不是n-1 , 反正写多点没错。 
    		for(int i = head[x] , v; i ; i = e[i].nex)
    		{
    			v = e[i].v;
    			if(dis[v] < dis[x] + e[i].c)
    			{
    				dis[v] = dis[x] + e[i].c;
    				if(!vis[v]) vis[v] = 1 , q.push(v);
    			}
    		}
    	}
    	return true;
    }
    
    int main()
    {
    	n = read(); m = read();
    	for(int i = 1 ; i <= m ; ++i) eu[i] = read() , ev[i] = read() , add(eu[i] , ev[i] , 0) , add(ev[i] , eu[i] , 0);
    	dfs1(1); 
    	if(!bo1[n]) { puts("-1"); return 0; } // 1 不能到 n 不连通 
    	dfs2(n);
    	for(int i = 1 ; i <= n ; ++i) if(bo1[i] && bo2[i]) bo[i] = 1; bo[1] = bo[n] = 1; // bo = 1 是有用点 
    	memset(head , 0 , sizeof head); cnt = 0; // 重复利用 
    	for(int i = 1 ; i <= m ; ++i)  // 建差分约束的边 
    		if(bo[eu[i]] && bo[ev[i]]) add(eu[i] , ev[i] , -9) , add(ev[i] , eu[i] , 1);
    	if(!SPFA()) { puts("-1"); return 0; } // 无解 
    	cout << n << ' ' << m << '
    ';
    	for(int i = 1 ; i <= m ; ++i) // 输出是判一下是不是在1到n的路径上 
    		cout << eu[i] << ' ' << ev[i] << ' ' << ((bo[eu[i]] && bo[ev[i]]) ? dis[eu[i]] - dis[ev[i]] : 1) << '
    ';
    	return 0;
    }
    
  • 相关阅读:
    IOS 网络编程 + 后台保持连接
    iOS 通过代码关闭应用程序
    iOS 委托和协议区别和联系
    对于WIFI版ipad(无GPS芯片)定位功能的释疑
    iOS单例
    svn不能添加.a文件的解决方法
    mac下SVN上传.a静态库文件
    iOS7 兼容及部分细节
    app被Rejected 的各种原因翻译
    iOS 沙盒购买,弹出“需要验证”,“继续登录”的问题?
  • 原文地址:https://www.cnblogs.com/R-Q-R-Q/p/12689996.html
Copyright © 2011-2022 走看看