锘??xml version="1.0" encoding="utf-8" standalone="yes"?> Description You’ve
finally got mad at “the world’s most stupid” employees of yours and
decided to do some firings. You’re now simply too mad to give response
to questions like “Don’t you think it is an even more stupid decision
to have signed them?”, yet calm enough to consider the potential profit
and loss from firing a good portion of them. While getting rid of an
employee will save your wage and bonus expenditure on him, termination
of a contract before expiration costs you funds for compensation. If
you fire an employee, you also fire all his underlings and the
underlings of his underlings and those underlings’ underlings’
underlings… An employee may serve in several departments and his
(direct or indirect) underlings in one department may be his boss in
another department. Is your firing plan ready now? Input The input starts with two integers n (0 < n ≤ 5000) and m (0 ≤ m ≤ 60000) on the same line. Next follows n + m lines. The first n lines of these give the net profit/loss from firing the i-th employee individually bi (|bi| ≤ 107, 1 ≤ i ≤ n). The remaining m lines each contain two integers i and j (1 ≤ i, j ≤ n) meaning the i-th employee has the j-th employee as his direct underling. Output Output
two integers separated by a single space: the minimum number of
employees to fire to achieve the maximum profit, and the maximum profit. Sample Input Sample Output Hint5 5
8
-9
-20
12
-10
1 2
2 5
1 4
3 4
4 52 2
鍏徃瑕佽鍛橈紝瑁佹帀涓涓憳宸ワ紝浠栫殑涓嬪睘涔熷緱瑁佹帀銆傝鎺変竴涓憳宸ュ彲浠ュ皯鍙戜竴瀹氱殑宸ヨ祫錛屼絾浠栧凡緇忎粬鐨勪笅灞炲叏琚鎺夛紝鎵浠ヨ繖涓猵artment浼氬噺灝戜竴瀹氱殑鐢熶駭鍒╂鼎銆傛樉鐒訛紝瑁佹帀涓涓漢灝卞彲鑳藉緱鍒版敹鐩婏紙姝g殑鎴栬呰礋鐨勶級錛?/span>
緇欏嚭瑁佹帀涓涓憳宸ヨ兘鑾峰緱鐨勬敹鐩婏紙姝f垨璐燂級銆?/span>
緇欏嚭鍏徃閲屽憳宸ョ殑渚濊禆鍏崇郴銆傝〃紺篈鏈変笅灞濨
闂緱鍒扮殑鏈澶у埄鐩婁互鍙婅鎺夌殑鏈灝戜漢鏁般?/span>
鍒嗘瀽錛氬湪榪欎簺浜轟腑閫夎嫢騫蹭漢錛屼嬌寰楁敹鐩婃渶澶с傚鏋淎鏈変笅灞濨錛岄偅鎴戣鎺堿灝卞緱瑁佹帀B銆傛墍浠ヨ鎺塀鎴愪簡瑁佹帀A鐨勫繀瑕佹潯浠訛紝鍗矨渚濊禆浜嶣銆傛墍浠ヨA榪炲悜B錛孉->B瀹歸噺涓烘鏃犵┓銆?/span>
閭d箞閫夎嫢騫蹭漢浜嬫晥鐩婃渶澶у氨鏄眰榪欎釜鏉冮棴鍚堝浘鐨勬渶澶у箋?/span>
涔嬪悗瀵逛簬鏀剁泭鏄鐨勪漢錛宻->x瀹歸噺涓烘敹鐩婂鹼紝瀵逛簬鏀剁泭鏄礋鐨勪漢x->t錛屽閲忎負鏀剁泭鍊煎緱緇濆鍊箋?/span>
緇撴灉灝辨槸姝f潈鍊煎拰-鏈灝忓壊鍊鹼紙鏈澶ф祦錛氬浘涓垏鍓叉渶灝忕殑鍊鹼級=鏈澶ф潈闂悎鍥劇殑鍊箋?/span>
榪欎釜鍥句粠s鍑哄彂鐨勮竟閮芥槸鏀剁泭錛屼粠x->t鐨勮竟閮芥槸娑堣椼傞偅姹傛渶灝忓壊灝辨槸瀵逛簬緇欏嚭鐨勮繖涔堝鐨勬敹鐩婏紝閫氳繃澶氬皯娑堣楄兘璁╁彇寰楃殑鏀剁泭鏈澶с?/span>
閭f渶鍚庣殑鍒╂鼎灝辨槸錛氭誨埄娑﹀拰-鍙栧緱鍒╂鼎鏈澶ф墍闇鐨勬秷鑰椼?/span>
#include <stdlib.h>
using namespace std;
const int maxn= 20010;
const __int64 inf=0x7fffffff;
struct node
{
__int64 v,next;
__int64 w;
}fn[500010];
__int64 level[maxn],g[maxn],que[maxn],out[maxn],th, tip, visit[maxn];
inline void add(__int64 u,__int64 v,__int64 w)
{
fn[th].v = v, fn[th].w = w, fn[th].next = g[u], g[u] = th++;
fn[th].v = u, fn[th].w = 0, fn[th].next = g[v], g[v] = th++;
}
void build_level(__int64 n,__int64 s,__int64 e)
{
__int64 h=0,r=0,i,u;
for (i = 0; i <= n; i++) level[i]=0;
level[s] = 1;
que[0] = s;
while(h <= r)
{
u = que[h++];
for (i = g[u]; i != -1; i = fn[i].next)
{
if (fn[i].w && level[fn[i].v] == 0)
{
que[++r] = fn[i].v;
level[fn[i].v] = level[u] + 1;
}
}
}
}
__int64 dinic(__int64 n,__int64 s,__int64 e)
{
__int64 ret=0,i;
while(1)
{
build_level(n,s,e);
if (level[e] == 0) break;
for (i = 0; i < n; ++i) out[i] = g[i];
__int64 q = -1;
while(1)
{
if (q < 0)
{
for (i = out[s]; i != -1; i = fn[i].next)
{
if (fn[i].w && out[fn[i].v] != -1 && level[fn[i].v] == 2)
{
que[++q] = i;
out[s] = fn[i].next;
break;
}
}
if (i == -1)
{
break;
}
}
__int64 u = fn[que[q]].v;
if(u == e)
{
__int64 tmp=inf;
for(i = 0;i <= q; i++)
if(tmp > fn[que[i]].w)tmp = fn[que[i]].w;
ret += tmp;
for(i=0;i<=q;i++)
{
fn[que[i]].w -= tmp;
fn[que[i]^1].w += tmp;
}
for (i = 0; i <= q; i++)
{
if(fn[que[i]].w == 0)
{
q = i-1;
break;
}
}
}
else
{
for (i = out[u]; i != -1; i = fn[i].next)
{
if (fn[i].w && out[fn[i].v] !=-1 && level[u] + 1 == level[fn[i].v])
{
que[++q] = i, out[u] = fn[i].next;
break;
}
}
if(i==-1)
{
out[u] = -1, q--;
}
}
}
}
return ret;
}
void dfs(int s, int e)
{
int i;
if (s == e)
{
return;
}
for (i = g[s]; i != -1; i++)
{
if (!visit[fn[i].v] && fn[i].w)
{
dfs(fn[i].v, e);
}
}
}
int main()
{
__int64 m, n, t, u, v, i, j, start, end, sum, num, w, ans;
int k = 0;
while (scanf("%I64d%I64d", &n, &m) - EOF)
{
k++;
start = 0, end = n + 1, th = 0;
for (i = 0; i <= end; i++)
{
g[i] = -1;
}
for (i = 1, sum = 0; i <= n; i++)
{
scanf("%I64d", &num);
if (num >= 0)
{
add(start, i, num);
sum += num;
}
else
{
add(i, end, -num);
}
}
for (j = 1; j <= m; j++)
{
scanf("%I64d%I64d", &u, &v);
add(u, v, inf);
}
sum -= dinic(end + 1, start, end);
tip = 0;
for (i = 0; i <= end + 1; i++)
{
visit[i] = 0;
}
dfs(0, end);
for (i = 0, tip = 0; i <= end + 1; i++)
{
if (visit[i])
{
tip++;
}
}
printf("%I64d %I64d\n", tip, ans);
}
//system("pause");
return 0;
}
]]>