无向图中给定单源,求到某点路径中最小权边的最大值。
可以将其看成求单源最短路径的变种,使用dijkstra算法+最大堆。
单源最短路径的算法是:记录从源点出发访问每一点i的最短路为value[i],对于当前所有value中的最小值点u,进行BFS式的操作,对于每条Edge(u,v),如果edge(u,v)+value[u] < value[v] 则更新v。这是一个贪心的算法,可以证明每次出队列的u最优。
本题求的是最大单边,对此稍做修改。记录每条边目前能承受的最大重量为value[i](即从源点所遍历路径的最小权中的最大值)。设u是当前结点,对于每条Edge(u,v),当路径扩展到v时的最小value(min(edge, value[u]))——即路径的最短边——大于value[v] 时更新。在联通图内,每一次要求的路径都是最大,因此在BFS的过程中,边是从大到小排列,对于当前所有value中的最大值点u进行操作。因为点的数目巨大,遍历需要N<100000,可以用堆存放value。实际程序里堆存放的是点的index,使用一个辅助数组来存放index在heap中的位置,如heap[1] = 6, idx[6] = 1。为了编程方便,heap以1开始。
由于边数目巨大(M<1000000),因此使用链表储存。使用num数组保存起点为i的起始位置,next数组保存链表。num[i]=a,next[a]=b,next[b]=c,next[c]=d,next[d]=0,这里abcd都为边数组中的位置,表示以i为起点的边终点为abcd。
1
#include <cstdio>
2
#include <string>
3![](http://www.cnitblog.com/Images/OutliningIndicators/None.gif)
4
#define min(x, y) ( x < y ? x : y )
5
#define INF 2000000001
6![](http://www.cnitblog.com/Images/OutliningIndicators/None.gif)
7
int N, M, src, dst, size;
8
const int MAXM = 1000010;
9
const int MAXN = 100001;
10![](http://www.cnitblog.com/Images/OutliningIndicators/None.gif)
11
typedef struct
12![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnitblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
13
int y, w;
14
} Edge;
15
Edge e[MAXM * 2];
16
int next[MAXM * 2], value[MAXN], visited[MAXN], num[MAXN], heap[MAXN], idx[MAXN];
17
//heap存放点序号,idx存放点在heap中的位置
18![](http://www.cnitblog.com/Images/OutliningIndicators/None.gif)
19
int init ();
20
int dijk ();
21
int get_top ();
22
void update ( int );
23
void print_heap ();
24
void print_value ();
25
void print_link ();
26![](http://www.cnitblog.com/Images/OutliningIndicators/None.gif)
27
int main ()
28![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnitblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
29
//freopen ( "in.txt", "r", stdin );
30
while ( init () )
31![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
32
printf ( "%d\n", dijk () );
33
}
34
return 0;
35
}
36![](http://www.cnitblog.com/Images/OutliningIndicators/None.gif)
37
int init ()
38![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnitblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
39
if ( scanf ( "%d%d", &N, &M ) != 2 )
40![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
41
return 0;
42
}
43
int i, j;
44
memset ( num, 0x00, sizeof ( num ) );
45
for ( i = 1, j = 0; i <= M; i ++ )
46![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
47
int tx, ty, tw;
48
scanf ( "%d%d%d", &tx, &ty, &tw );
49
e[++ j].w = tw, e[j].y = ty, next[j] = num[tx], num[tx] = j;
50
e[++ j].w = tw, e[j].y = tx, next[j] = num[ty], num[ty] = j;
51
}
52
scanf ( "%d%d", &src, &dst );
53
memset ( value, 0, sizeof ( value ) );
54
memset ( visited, 0, sizeof ( visited ) );
55
memset ( idx, 0, sizeof ( idx ) );
56
return 1;
57
}
58![](http://www.cnitblog.com/Images/OutliningIndicators/None.gif)
59
int dijk ()
60![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnitblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
61
size = 0;
62
value[src] = INF, visited[src] = 1;
63
heap[++ size] = src, idx[src] = 1;
64
while ( true )
65![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
66
if ( visited[dst] || size == 0 )
67![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
68
break;
69
}
70
int j, u, v;
71
u = get_top ();
72
visited[u] = 1;
73
for ( j = num[u]; j; j = next[j] )
74![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
75
v = e[j].y;
76
if ( !visited[v] && value[v] < min ( value[u], e[j].w ) )
77![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
78
if ( idx[v] == 0 )
79![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
80
heap[++ size] = v;
81
idx[v] = size;
82
}
83
value[v] = min ( value[u], e[j].w );
84
update ( v );
85
}
86
}
87
}
88
return value[dst];
89
}
90![](http://www.cnitblog.com/Images/OutliningIndicators/None.gif)
91
int get_top ()
92![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnitblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
93
int res = heap[1], p = 1, q = 2, r = heap[size --];
94
while ( q <= size )
95![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
96
if ( q < size && value[heap[q + 1]] > value[heap[q]] )
97![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
98
q ++;
99
}
100
if ( value[heap[q]] > value[r] )
101![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
102
idx[heap[q]] = p;
103
heap[p] = heap[q];
104
p = q; q = p << 1;
105
}
106
else
107![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
108
break;
109
}
110
}
111
heap[p] = r; idx[r] = p;
112
return res;
113
}
114![](http://www.cnitblog.com/Images/OutliningIndicators/None.gif)
115
void update ( int r )
116![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnitblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
117
int q = idx[r], p = q >> 1;
118
while ( p && value[heap[p]] < value[r] )
119![](http://www.cnitblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
120
idx[heap[p]] = q; heap[q] = heap[p];
121
q = p; p = q >> 1;
122
}
123
heap[q] = r; idx[r] = q;
124
}
125![](http://www.cnitblog.com/Images/OutliningIndicators/None.gif)
126![](http://www.cnitblog.com/Images/OutliningIndicators/None.gif)
评论