码迷,mamicode.com
首页 > 编程语言 > 详细

“Hdu4966” GGS-DDU - 最小树形图/朱刘算法

时间:2019-08-26 09:24:38      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:引用   int   struct   需要   name   number   problem   max   des   

原文引用https://www.dazhuanlan.com/2019/08/26/5d6302f8c23db/


题目链接:传送门

Description

有一个人,想学习N个科目,每个科目都有相应的层次 有M个课程,M个课程的要求是,你的第c个科目的层次要达到l1,才可以参加,参加完这个课程后,你需要缴费money,但你的第d个科目的层次会达到l2 问如何花最少的钱,使得每个科目的层次都达到最高

Solution

每个科目的每个层次都看成一个点,每个科目的层次0和一个根连边,费用为0;每个科目的高层次向下一个低层次连边,费用为0(因为你高层次的会了就表示低层次的也会了) 然后用朱刘算法跑一遍最小树形图即可

Code

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129


using namespace std;

const int Maxn = 500 + 10, Maxm = 2500 + 10, inf = INT_MAX;

struct node
{
int x, y, w;
}edge[Maxm];

int N, M, cnt, Ans, Index;
int Map[55][500 + 10];

inline void Init()
{
cnt = Ans = Index = 0;
}

inline void add_edge (int x, int y, int z)
{
edge[++cnt].x = x;
edge[cnt].y = y;
edge[cnt].w = z;
}

int In[Maxn], Pre[Maxn];
int id[Maxn], Vis[Maxn];

inline int Solve (int root)
{
while (1)
{
for (int i = 1; i <= N; ++i) In[i] = inf;
for (int i = 1; i <= cnt; ++i)
{
int x = edge[i].x, y = edge[i].y;
if (x != y && edge[i].w < In[y])
{
Pre[y] = x;
In[y] = edge[i].w;
}
}
for (int i = 1; i <= N; ++i)
if (i != root && In[i] == inf) return -1;

int sum = 0;
memset(id, -1, sizeof id);
memset(Vis, -1, sizeof Vis);
In[root] = 0;
for (int i = 1; i <= N; ++i)
{
Ans += In[i];
int now = i;
while (Vis[now] != i && now != root && id[now] == -1)
{
Vis[now] = i;
now = Pre[now];
}

if (now != root && id[now] == -1)
{
int tmp = Pre[now];
++sum;
while (tmp != now)
{
id[tmp] = sum;
tmp = Pre[tmp];
}
id[now] = sum;
}
}
if (!sum) return Ans;

for (int i = 1; i <= N; ++i)
if (id[i] == -1) id[i] = ++sum;
for (int i = 1; i <= cnt; ++i)
{
int x = edge[i].x, y = edge[i].y;
edge[i].x = id[x]; edge[i].y = id[y];
if (id[x] != id[y])
edge[i].w -= In[y];
}
N = sum;
root = id[root];
}
}

int main()
{
#ifdef hk_cnyali
freopen("A.in", "r", stdin);
freopen("A.out", "w", stdout);
#endif
while (1)
{
scanf("%d%d", &N, &M);
if (N == M && !N) break;
Init();
for (int i = 1; i <= N; ++i)
{
int x;
scanf("%d", &x);
for (int j = 0; j <= x; ++j)
Map[i][j] = ++Index;
Map[i][501] = x;
}
while (M--)
{
int a, b, c, d, e;
scanf("%d%d%d%d%d", &a, &b, &c, &d, &e);
add_edge(Map[a][b], Map[c][d], e);
}

for (int i = 1; i <= N; ++i)
for (int j = 1; j <= Map[i][501]; ++j)
{
add_edge(Map[i][j], Map[i][j - 1], 0);
}

for (int i = 1; i <= N; ++i)
add_edge(0, Map[i][0], 0);

N = Index;

printf("%dn", Solve(0));
}
return 0;
}

“Hdu4966” GGS-DDU - 最小树形图/朱刘算法

标签:引用   int   struct   需要   name   number   problem   max   des   

原文地址:https://www.cnblogs.com/petewell/p/11410482.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!