您的位置:首页 > 其它

hdu 5385 The path(贪心)

2015-08-15 21:13 447 查看
## hdu 5385 The path ##

Problem Description

You have a connected directed graph.Let d(x) be the length of the shortest path from 1 to x.Specially d(1)=0.A graph is good if there exist x satisfy d(1) < d(2) < ….d(x) > d(x+1) > …d(n).Now you need to set the length of every edge satisfy that the graph is good.Specially,if d(1) < d(2) < ..d(n),the graph is good too.

The length of one edge must ∈ [1,n]

It’s guaranteed that there exists solution.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains two integers n and m,the number of vertexs and the number of edges.Next m lines contain two integers each, ui and vi (1≤ui,vi≤n), indicating there is a link between nodes ui and vi and the direction is from ui to vi.

∑n≤3∗105,∑m≤6∗105

1≤n,m≤105

Output

For each test case,print m lines.The i-th line includes one integer:the length of edge from ui to vi

Sample Input

2

4 6

1 2

2 4

1 3

1 2

2 2

2 3

4 6

1 2

2 3

1 4

2 1

2 1

2 1

Sample Output

1

2

2

1

4

4

1

1

3

4

4

4

题目大意:一张图有N个顶点,给出一些有向边,问该如何给这些边赋值才能满足d(1) < d(2) < ….d(x) > d(x+1) > …d(n) 的条件且1为起点,d(x)表示1到x的最短距离. 赋值的范围在1~N。

解题思路:左边从2开始,右边从n开始,每次选与之前标记过的点相连的未标记过得点,该点的d[i]为该点加入的时间。最后输出时,判断该点是否在最短路上,不在的话,输出n,在的话输出d[v] - d[u]。

[code]#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;

const int N = 300005;
const int M = 600005;
typedef long long ll;
int n, m;
int head[M], vis
;
int d[M], ec;
struct Edge{
    int from, to, next;
}edges[M];

void addEdge(int u, int v) {
    edges[ec].from = u;
    edges[ec].to = v;
    edges[ec].next = head[u];
    head[u] = ec++;
}

void init() {
    memset(head, -1, sizeof(head));
    memset(vis, 0, sizeof(vis));
    ec = 0;
    d[1] = 0;
    d[2] = 1;
    d
 = 1;
    vis[1] = -1;
}

void mark(int u) { //标记已标记点u所相连的未标记的点
    for (int i = head[u]; i != -1; i = edges[i].next) {
        int v = edges[i].to;    
        if (!vis[v]) vis[v] = u;
    }
}

void input() {
    int a, b;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d %d", &a, &b);         
        addEdge(a, b);
    }
}

void solve() {
    int l = 1, r = n, val = 1;  
    while (l <= r) { //从2和n开始加点,d[i]为点i加入的时间
        if (vis[l]) {
            mark(l);    
            d[l++] = val++;
        }   
        if (vis[r]) {
            mark(r);        
            d[r--] = val++;
        }
    }
    for (int i = 0; i < ec; i++) {
        int u = edges[i].from, v = edges[i].to;
        if (vis[v] != u) printf("%d\n", n); //不在最短路树上的边
        else printf("%d\n", d[v] - d[u]); //最短路树上的边
    }
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        init();
        input();
        solve();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: