有乙個m * n的棋盤,有的格仔是障礙。現在你要選擇一些格仔來放置一些士兵,乙個格仔裡最多可以放置乙個士兵,障礙格里不能放置士兵。我們稱這些士兵占領了整個棋盤當滿足第i行至少放置了li個士兵, 第j列至少放置了cj個士兵。現在你的任務是要求使用最少個數的士兵來占領整個棋盤。
第一行兩個數m, n, k分別表示棋盤的行數,列數以及士兵的個數。 第二行有m個數表示li。 第三行有n個數表示ci。 接下來有k行,每行兩個數x, y表示(x, y)這個格仔是障礙。
輸出乙個數表示最少需要使用的士兵個數。如果無論放置多少個士兵都沒有辦法占領整個棋盤,輸出」jiong!」 (不含引號)
輸入 #1複製
4 4 4輸出 #1複製1 1 1 1
0 1 0 3
1 42 2
3 34 3
4求最少顯然用上下界網路流比較方便
#includeusingview codenamespace
std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ri(n) scanf("%d",&(n))
#define rii(n,m) scanf("%d%d",&n,&m)
#define riii(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define rs(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define clr(a,v) memset(a,v,sizeof a)
/////////////////////////////////
/const
int n=100001
;ll maxflow,mincost;
intlast[n],pre[n],dis[n],flow[n],d[n];
bool
vis[n];
struct
edgeedge[n
<<1
];int pos=1
,head[n];
void
init()
queue
q;inline
void add(int
from,int to,int flow,int dis)//
flow流量 dis費用
void ins(int x,int y,int down,int up,int
cost)
bool spfa(int s,int
t) }}}
return pre[t]!=-1;}
inline
void mcmf(int s,int
t) }
}int n,m,s,t,ss,x,a,b,s,t,mp[200][200
],k;
int id(int x,int
y)int
main()
rep(i,
1,n)rep(j,1
,m)
if(mp[i][j]==0)ins(n*m+i,n*m+n+j,0,1,1
); ins(t,s,
0,inf,0
); rep(i,
1,t)
if(d[i]>0)add(s,i,d[i],0
);
else
if(d[i]<0)add(i,t,-d[i],0
); mcmf(s,t);
cout
<
return0;
}
也可以用普通的最大流來解逆向思考 在滿足條件的情況下最多刪除多少士兵
對於格仔ij 如果不是障礙的話 連行i 列j 容量為1 表示最多刪除乙個
建立源點s 連每行 容量為 m-該行障礙數-該行至少多少個 匯點同理
跑一下最大流就行了。。
上下界費用流
codeforces 708d incorrect flow 這是道可行流最小費用的題目,這題好神奇。看這老哥的題解就ok了。戳這 我覺得他少說了一條邊,但 中卻體現了,就是一條流量為 f,f 的邊,費用為0,就是固定流量的一條邊。還要注意一點是,f c 的時候,f 往下調到 c 以下時,c 是不動...
上下界網路流及費用流學習筆記
前言 不錯的文章 無源匯上下界可行流 模型 乙個網路,求出乙個流,使得每條邊的流量必須 l ge l l且 r le r r,每個點必須滿足總流入量 總流出量 流量守恆 這個流的特點是迴圈往復,無始無終 考慮到如果存在乙個可行流,那麼每條邊的流量至少是 l ll,於是我們可以預先讓它先流 lll 這...
P4553 80人環遊世界 上下界可行費用流
link 無特殊說明費用都是0 新建源點s ss和匯點t tt,新建虛擬限制節點xun ixuni xuni s ss連向xun ixuni xuni 流量 0,m 0,m 0,m 的邊,表示可以派出的人不能超過mmm x un ixuni xuni 連向每個點流量 0,inf 0,inf 0,in...