MYF

HDU 5385 The path

题目链接

HDU 5385

方法:借鉴dijkstra,构造dis数组

题目分析

题目大意

给出n个点,m条有向边,问这m条边如何赋值,可以使d(1)<d(2)<....<d(x-1)<d(x)>d(x+1)>...d(n)

解析

借鉴dijkstra的dis[]数组,在dijkstra的最短路中,该数组是用于记录到source的最短距离,然后对于给定的边,再用该边的两个端点的dis[]值做差

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Memset(a,val) memset(a,val,sizeof(a))
#define PI acos(-1)
#define rt(n) (i == n ? '\n' : ' ')
#define hi printf("Hi----------\n")
#define IN freopen("input.txt","r",stdin);
#define OUT freopen("output.txt","w",stdout);
#define debug(x) cout<<"Debug : ---"<<x<<"---"<<endl;
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long ll;
using namespace std;
const int maxn=100000+5;
const int mod=1000000007;
const int INF=0x3f3f3f3f;
const double eps=1e-8;
int head[maxn],ecnt,dis[maxn];
struct edge{
int u,v,next;
}e[maxn];
void init(){
Memset(head, -1);
Memset(dis, 0);
ecnt=0;
}
void adde(int u,int v){
e[ecnt].u=u;
e[ecnt].v=v;
e[ecnt].next=head[u];
head[u]=ecnt++;
}
int main(){
int n,m,t,x,y;
scanf("%d",&t);
while (t--) {
init();
scanf("%d%d",&n,&m);
for (int i=0; i<m; i++) {
scanf("%d%d",&x,&y);
adde(x,y);
}

set<int> st;
//存储所有直接连接1的点
for (int i=head[1]; i!=-1; i=e[i].next) {
st.insert(e[i].v);
}


int cnt=1;//已经找到dis的点的数量
int left=2,right=n,tmp;//左侧匹配指针 右侧匹配指针

while (cnt!=n) {

//找到左指针的dis 左指针右移 否则右指针左移
if (st.count(left))
tmp=left++;
else
tmp=right--;
dis[tmp]=cnt++;

//将本次找到的点的所有相邻点加入集合
for (int i=head[tmp]; i!=-1; i=e[i].next) {
st.insert(e[i].v);
}
}

for (int i=0; i<m; i++) {
if (e[i].v==e[i].u)
printf("%d\n",n);
else
printf("%d\n",abs(dis[e[i].u]-dis[e[i].v]));// 距离为两dis值之差
}
}
}