zoukankan      html  css  js  c++  java
  • 【CF241E】Flights

    题目描述

    LiLand is a country, consisting of (n) cities. The cities are numbered from (1) to (n) . The country is well known because it has a very strange transportation system. There are many one-way flights that make it possible to travel between the cities, but the flights are arranged in a way that once you leave a city you will never be able to return to that city again.

    Previously each flight took exactly one hour, but recently Lily has become the new manager of transportation system and she wants to change the duration of some flights. Specifically, she wants to change the duration of some flights to exactly (2) hours in such a way that all trips from city (1) to city (n) take the same time regardless of their path.

    Your task is to help Lily to change the duration of flights.

    题目大意

    给定一张有向图,要求给每一条边赋上 (1)(2) 的边权,使点 (1)(n) 的所有路径长度相等

    思路

    回顾一下差分约束

    可以发现点 (1) 到任意点的所有路径的长度均相等

    所以只要构造出一个以点 (1) 为原点的最短路 ({dis_i}) 数组,对于一条边 (u o v) 给它赋上 (dis_v-dis_u) 的边权,就可以满足题目了

    题中要求边权为 (1)(2),对于一条边 (u o v) 都有 (1le dis_v-dis_ule 2),差分约束就好了

    注意这个约束只对点 (1)(n) 路径上的边,要先标出路径上的边,其他的随意赋成 (1/2)

    #include <algorithm>
    #include <utility>
    #include <cstdio>
    #include <vector>
    using namespace std;
    const int maxn = 5e3 + 10;
    bool vis[maxn][2],vi[maxn];
    vector<int> edge[maxn][2];
    pair<int,int> e[maxn];
    int n,m,dis[maxn];
    inline void dfs(int now,int w) {
    	vis[now][w] = true;
    	for (size_t i = 0;i < edge[now][w].size();i++) {
    		int to = edge[now][w][i];
    		if (!vis[to][w]) dfs(to,w);
    	}
    }
    int main() {
    	scanf("%d%d",&n,&m);
    	for (int i = 1,u,v;i <= m;i++) {
    		scanf("%d%d",&u,&v);
    		e[i] = make_pair(u,v);
    		edge[u][0].push_back(v);
    		edge[v][1].push_back(u);
    	}
    	dfs(1,0); dfs(n,1);
    	for (int i = 1;i <= n;i++) vi[i] = vis[i][0]&vis[i][1];
    	for (int j = 1;j <= n+m;j++)
    		for (int i = 1;i <= m;i++) {
    			int u = e[i].first,v = e[i].second;
    			if (vi[u] & vi[v]) {
    				dis[u] = max(dis[u],dis[v]-2);
    				dis[v] = max(dis[v],dis[u]+1);
    			}
    		}
    	for (int i = 1;i <= m;i++) {
    		int u = e[i].first,v = e[i].second;
    		if ((vi[u] & vi[v]) && (dis[v]-dis[u] < 1 || dis[v]-dis[u] > 2))
    			return printf("No"),0;
    	}
    	printf("Yes
    ");
    	for (int i = 1;i <= m;i++) {
    		int u = e[i].first,v = e[i].second;
    		if (vi[u] & vi[v]) printf("%d
    ",dis[v]-dis[u]);
    		else printf("1
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    (转载)机器学习方法的PPT
    算法的力量(转李开复)
    CNKI免费帐号
    图像增强(二)
    初始化 Microsoft Visual SourceSafe 源代码管理提供程序时失败。您无法使用此提供程序执行源代码管理操作。”
    2012年"浪潮杯"山东省第三届ACM大学生程序设计竞赛 Fruit Ninja I
    hdu 3607 Traversal
    zoj 3686 A Simple Tree Problem
    hdu 3727 Jewel
    hdu 4366 Successor
  • 原文地址:https://www.cnblogs.com/lrj124/p/14410119.html
Copyright © 2011-2022 走看看