hdu 5385 The path

来源:互联网 发布:免费的fq软件 编辑:程序博客网 时间:2024/05/25 01:36
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 (1ui,vin), indicating there is a link between nodes ui and vi and the direction is from ui to vi.n3105,m61051n,m105
 

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
24 61 22 41 31 22 22 34 61 22 31 42 12 12 1
 

Sample Output
122144113444




#include <iostream>#include<vector>#include<algorithm>#include<cstring>#include<cstdio>#include<queue>using namespace std;const int mx=500000;int T,n,m;struct edge{    int to,id;};vector<edge> g[mx];int used[mx],id[mx];struct EG{    int u,v,dis;} eg[mx];void init(){    for(int i=0;i<=n;i++) g[i].clear();}void add_edge(int u,int v,int id){    g[u].push_back(edge{v,id});}int main(){    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        init();        for(int i=1;i<=m;i++)        {            int u,v;            scanf("%d%d",&u,&v);            add_edge( u, v,i);            eg[i].u=u;eg[i].v=v;eg[i].dis=n;        }        queue<int> que;        vector<int> ans;        que.push(1);memset(used,0,sizeof(used));used[1]=1;        int tar1=2,tar2=n;        while(!que.empty())        {            int u=que.front();ans.push_back(u);que.pop();            for(int i=0;i<g[u].size();i++)            {                int v=g[u][i].to;                if(!used[v]) used[v]=g[u][i].id;            }            while(tar1<=tar2&&used[tar1]) {que.push(tar1);tar1++;}            while(tar2>=tar1&&used[tar2]) {que.push(tar2);tar2--;}        }        for(int i=0;i<ans.size();i++)        {            id[ans[i]]=i;        }        for(int i=2;i<=n;i++)        {            EG &t=eg[used[i]];            t.dis=abs(id[t.u]-id[t.v] );        }        for(int i=1;i<=m;i++)        {            printf("%d\n",eg[i].dis);        }    }    return 0;}

1006.The path

如果我们知道每个点的disdis值和最短路径树的话,方案是很容易构造的

我们可以采取贪心做法,一开始将11号点作为最短路径树的根,然后左边从22开始,右边从nn开始,只要之前加入的点有边连向他们就加入

这样一个点加入的时间就是他的disdis值,最短路径树上的父亲也可以确定,于是输出时非树边长度为nn,树边长度为两个端点disdis之差

刚开始看成无向图,WA了半天

0 0
原创粉丝点击