1273 Drainage Ditches (1)
1274 The Perfect Stall (1)
2112 Optimal Milking (4)
3041 Asteroids (5)
3308 Paratroopers (6)
2195 Going Home (6)
2516 Minimum Cost (7)
2455 Secret Milking Machine (7)
2226 Muddy Fields (7)
3281 Dining (7)
2391 Ombrophobic Bovines (8, challenge problem)
3498 March of the Penguins (8, challenge problem)
poj2195
最小费用二分图匹配的三种方式
#include
#include
#include
#include
#include
#include
using namespace std;
typedef vector VI;
typedef vector VVI;
typedef long long L;
typedef vector VL;
typedef vector VVL;
typedef pair PII;
typedef vector VPII;
typedef vector VD;
typedef vector VVD;
const L INF = 0x3f3f3f3f;
struct MinCostMaxFlow {
int N;
VVL cap, flow, cost;
VI found;
VL dist, pi, width;
VPII dad;
MinCostMaxFlow(int N) :
N(N), cap(N, VL(N)), flow(N, VL(N)), cost(N, VL(N)),
found(N), dist(N), pi(N), width(N), dad(N) {}
void AddEdge(int from, int to, L cap, L cost) {
this->cap[from][to] = cap;
this->cost[from][to] = cost;
}
void Relax(int s, int k, L cap, L cost, int dir) {
L val = dist[s] + pi[s] - pi[k] + cost;
if (cap && val < dist[k]) {
dist[k] = val;
dad[k] = make_pair(s, dir);
width[k] = min(cap, width[s]);
}
}
L Dijkstra(int s, int t) {
fill(found.begin(), found.end(), false);
fill(dist.begin(), dist.end(), INF);
fill(width.begin(), width.end(), 0);
dist[s] = 0;
width[s] = INF;
while (s != -1) {
int best = -1;
found[s] = true;
for (int k = 0; k < N; k++) {
if (found[k]) continue;
Relax(s, k, cap[s][k] - flow[s][k], cost[s][k], 1);
Relax(s, k, flow[k][s], -cost[k][s], -1);
if (best == -1 || dist[k] < dist[best]) best = k;
}
s = best;
}
for (int k = 0; k < N; k++)
pi[k] = min(pi[k] + dist[k], INF);
return width[t];
}
pair GetMaxFlow(int s, int t) {
L totflow = 0, totcost = 0;
while (L amt = Dijkstra(s, t)) {
totflow += amt;
for (int x = t; x != s; x = dad[x].first) {
if (dad[x].second == 1) {
flow[dad[x].first][x] += amt;
totcost += amt * cost[dad[x].first][x];
} else {
flow[x][dad[x].first] -= amt;
totcost -= amt * cost[x][dad[x].first];
}
}
}
return make_pair(totflow, totcost);
}
};
int ht,mt;
char mat[110][110];
typedef pair pii;
pii house[110],man[110];
int dis(int i,int j){
return abs(house[i].first-man[j].first)+abs(house[i].second-man[j].second);
}
void gao_mcmf(){
MinCostMaxFlow my(ht+ht+2);
for(int i=0;i new_dist) {
dist[k] = new_dist;
dad[k] = j;
}
}
}
// update dual variables
for (int k = 0; k < n; k++) {
if (k == j || !seen[k]) continue;
const int i = Rmate[k];
v[k] += dist[k] - dist[j];
u[i] -= dist[k] - dist[j];
}
u[s] += dist[j];
// augment along path
while (dad[j] >= 0) {
const int d = dad[j];
Rmate[j] = Rmate[d];
Lmate[Rmate[j]] = j;
j = d;
}
Rmate[j] = s;
Lmate[s] = j;
mated++;
}
double value = 0;
for (int i = 0; i < n; i++)
value += cost[i][Lmate[i]];
return value;
}
VI Lmate,Rmate;
void gao_mcmatch(){
VD temp(ht,0);
VVD cost(ht,temp);
for(int i=0;i adj[maxn],nu;
vector::iterator pre[maxn];
queue q;
int cnt[maxn];
int d[maxn];
bool vis[maxn];
void add(int u,int v,int c,int w){
adj[u].push_back(NODE(u,v,c,w,adj[v].size()));
adj[v].push_back(NODE(v,u,0,-w,adj[u].size()-1));
}
int n;
int spfa(){
while(!q.empty()) q.pop();
fill(d,d+n+2,INF);
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(vis));
d[0]=0;
cnt[0]=1;
vis[0]=1;
pre[0]=nu.begin();
q.push(0);
int u,v,c;
vector::iterator it;
while(!q.empty()){
u=q.front();
q.pop();
vis[u]=0;
for(it=adj[u].begin();it!=adj[u].end();++it){
v=it->v;
if(it->c && d[v]>d[u]+it->w){
d[v]=d[u]+it->w;
pre[v]=it;
if(!vis[v]){
if(++cnt[v]>n+1) return 0;
vis[v]=1;
q.push(v);
}
}
}
}
if(d[n+1]==INF) return 0;
return 1;
}
int mfmc(){
int ans=0,m;
vector::iterator it;
while(spfa()){
m=INF;
for(it=pre[n+1];it!=nu.begin();it=pre[it->u]){
m=min(m,it->c);
}
for(it=pre[n+1];it!=nu.begin();it=pre[it->u]){
it->c-=m;
adj[it->v][it->p].c+=m;
}
ans+=m*d[n+1];
}
return ans;
}
void gao_mfmc(){
int i,j;
n=ht+ht;
for(i=0;i<=n+1;++i) adj[i].clear();
for(int i=0;i
poj2516
最大流最小费模板
#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 110
int cost[55][55][55];
int buy[55][55],sell[55][55],bt[55],st[55];
struct NODE{
NODE(){}
NODE(int uu,int vv,int cc,int ww,int pp):u(uu),v(vv),c(cc),w(ww),p(pp){}
int u,v,c,w,p;
};
vector adj[maxn],nu;
vector::iterator pre[maxn];
queue q;
int cnt[maxn];
int d[maxn];
bool vis[maxn];
void add(int u,int v,int c,int w){
adj[u].push_back(NODE(u,v,c,w,adj[v].size()));
adj[v].push_back(NODE(v,u,0,-w,adj[u].size()-1));
}
int n,B,S,K;
int spfa(){
while(!q.empty()) q.pop();
fill(d,d+n+2,INF);
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(vis));
d[0]=0;
cnt[0]=1;
vis[0]=1;
pre[0]=nu.begin();
q.push(0);
int u,v,c;
vector::iterator it;
while(!q.empty()){
u=q.front();
q.pop();
vis[u]=0;
for(it=adj[u].begin();it!=adj[u].end();++it){
v=it->v;
if(it->c && d[v]>d[u]+it->w){
d[v]=d[u]+it->w;
pre[v]=it;
if(!vis[v]){
if(++cnt[v]>n+1) return 0;
vis[v]=1;
q.push(v);
}
}
}
}
if(d[n+1]==INF) return 0;
return 1;
}
int mfmc(){
int ans=0,m;
vector::iterator it;
while(spfa()){
m=INF;
for(it=pre[n+1];it!=nu.begin();it=pre[it->u]){
m=min(m,it->c);
}
for(it=pre[n+1];it!=nu.begin();it=pre[it->u]){
it->c-=m;
adj[it->v][it->p].c+=m;
}
ans+=m*d[n+1];
}
return ans;
}
int gao_mfmc(int k){
int i,j;
for(i=0;i<=n+1;++i) adj[i].clear();
for(i=0;ist[i]){
ok=0;
break;
}
}
if(!ok){
printf("-1\n");
continue;
}
int ans=0;
for(i=0;i
以连续线段为结点,最大二分匹配(匈牙利算法)
#include
#include
#define maxn 1300
int mat[maxn][maxn],match[maxn];
bool vis[maxn];
char map[55][55];
int r[55][55],c[55][55];
int cntr,cntc;
int m,n;
bool dfs(int i){
int j;
for(j=0;j0 && map[i][j-1]=='*') ++cntr;
}
}
for(j=0;j0 && map[i-1][j]=='*') ++cntc;
}
}
for(i=0;i
floyd+离散化+二分+dinic
#include
#include
#include
#include
#include
using namespace std;
typedef long long u64;
typedef int type;
#define maxn 205
#define maxm 81205
#define INF 0x3ffffffffffffLL
#define inf 0x3f3f3f3f
struct EDGE{
int v,next;
type c;
}edge[maxm];
u64 mat[maxn][maxn];
int n,N,M;
int have[maxn],hold[maxn];
int d[maxn<<1],head[maxn<<1];
int src,des,tot,all;
void init(){
memset(head,-1,sizeof(head));
tot=0;
}
void add(int u,int v,type c){
edge[tot].v=v,edge[tot].c=c,edge[tot].next=head[u];head[u]=tot++;
edge[tot].v=u,edge[tot].c=0,edge[tot].next=head[v];head[v]=tot++;
}
queue q;
bool bfs(){
while(!q.empty()) q.pop();
int u,v,i;
type c;
memset(d,-1,sizeof(d));
d[src]=0;
q.push(src);
while(!q.empty()){
u=q.front();
q.pop();
for(i=head[u];i!=-1;i=edge[i].next){
v=edge[i].v;
c=edge[i].c;
if(c>0 && d[v]==-1){
d[v]=d[u]+1;
q.push(v);
}
}
}
return (d[des]!=-1);
}
type dfs(int u,type mm){
if(u==des) return mm;
int i,v;
type c,temp;
for(i=head[u];i!=-1;i=edge[i].next){
v=edge[i].v;
c=edge[i].c;
if(c>0 && d[v]==d[u]+1 && (temp=dfs(v,min(mm,c)))){
edge[i].c-=temp;
edge[i^1].c+=temp;
return temp;
}
}
d[u]=-1;
return 0;
}
type dinic(){
type ans=0,temp;
while(bfs()){
while(1){
temp=dfs(src,inf);
if(!temp) break;
ans+=temp;
}
}
return ans;
}
bool check(u64 k){
int i,j;
init();
for(i=1;i<=N;++i){
for(j=1;j<=N;++j){
if(mat[i][j]<=k && i!=j && have[i]){
add(i,j+N,have[i]);
}
}
if(have[i]){
add(i,N+i,have[i]);
add(src,i,have[i]);
}
if(hold[i]){
add(i+N,des,hold[i]);
}
}
if(dinic()==all) return 1;
return 0;
}
u64 h[maxn*maxn];
int cnt;
int main(){
//freopen("data.in","r",stdin);//freopen("data.out","w",stdout);
int i,j,u,v,k,l,r,m;
u64 c;
scanf("%d%d",&N,&M);
for(i=1;i<=N;++i){
scanf("%d%d",&have[i],&hold[i]);
all+=have[i];
for(j=1;j<=N;++j) mat[i][j]=INF;
}
while(M--){
scanf("%d%d%lld",&u,&v,&c);
mat[u][v]=min(mat[u][v],c);
mat[v][u]=min(mat[v][u],c);
}
for(k=1;k<=N;++k){
for(i=1;i<=N;++i){
for(j=1;j<=N;++j){
mat[i][j]=min(mat[i][j],mat[i][k]+mat[k][j]);
}
}
}
cnt=1;
for(i=1;i<=N;++i){
for(j=i+1;j<=N;++j){
if(mat[i][j]!=INF){
h[cnt++]=mat[i][j];
}
}
}
n=N+N+2;
src=0,des=n-1;
sort(h,h+cnt);
cnt=unique(h,h+cnt)-h;
l=0,r=cnt-1;
if(!check(h[r])){
printf("-1\n");
return 0;
}
while(l+1>1;
// printf("l=%d r=%d h[m]=%lld\n",l,r,h[m]);
if(check(h[m])) r=m;
else l=m;
}
printf("%lld\n",h[r]);
return 0;
}