您的位置:首页 > 其它

hdu 5385 The path

2015-08-13 21:38 537 查看
[align=left]Problem Description[/align]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.
[align=left]Input[/align]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
[align=left]Output[/align]For each test case,print m lines.The i-th line includes one integer:the length of edge from ui to vi
[align=left]Sample Input[/align]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

[align=left]Sample Output[/align]
1
2
2
1
4
4
1
1
3
4
4
4


#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了半天
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: