hdu 1532
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
const int Ni = 210;
const int MAX = 1<<26;
struct Edge{
int u,v,c;
int next;
}edge[20*Ni];
int n,m;
int edn;//边数
int p[Ni];//父亲
int d[Ni];
int sp,tp;//原点,汇点
void addedge(int u,int v,int c)
{
edge[edn].u=u; edge[edn].v=v; edge[edn].c=c;
edge[edn].next=p[u]; p[u]=edn++;
edge[edn].u=v; edge[edn].v=u; edge[edn].c=0;
edge[edn].next=p[v]; p[v]=edn++;
}
int bfs()
{
queue <int> q;
memset(d,-1,sizeof(d));
d[sp]=0;
q.push(sp);
while(!q.empty())
{
int cur=q.front();
q.pop();
for(int i=p[cur];i!=-1;i=edge[i].next)
{
int u=edge[i].v;
if(d[u]==-1 && edge[i].c>0)
{
d[u]=d[cur]+1;
q.push(u);
}
}
}
return d[tp] != -1;
}
int dfs(int a,int b)
{
int r=0;
if(a==tp)return b;
for(int i=p[a];i!=-1 && r<b;i=edge[i].next)
{
int u=edge[i].v;
if(edge[i].c>0 && d[u]==d[a]+1)
{
int x=min(edge[i].c,b-r);
x=dfs(u,x);
r+=x;
edge[i].c-=x;
edge[i^1].c+=x;
}
}
if(!r)d[a]=-2;
return r;
}
int dinic(int sp,int tp)
{
int total=0,t;
while(bfs())
{
while(t=dfs(sp,MAX))
total+=t;
}
return total;
}
int main()
{
int i,u,v,c;
while(~scanf("%d%d",&m,&n))
{
edn=0;//初始化
memset(p,-1,sizeof(p));
sp=1;tp=n;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&c);
addedge(u,v,c);
}
printf("%d\n",dinic(sp,tp));
}
return 0;
}
hdu 3572
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x7fffffff
#define maxn 25000
using namespace std;
struct Edge{
int from,to,cap,flow;
};
class Dinic{
private:
int s,t,c;
vector<Edge>edges;
vector<int>G[maxn];//结点
bool vis[maxn];
int dist[maxn];
int cur[maxn];
public:
int n,m;
void AddEdge(int from,int to,int cap){
edges.push_back((Edge){from,to,cap,0});
edges.push_back((Edge){to,from,0,0});
c=edges.size();
G[from].push_back(c-2);
G[to].push_back(c-1);
}
bool BFS(){
queue<int>Q;
memset(vis,0,sizeof(vis));
Q.push(s);
dist[s]=0;
vis[s]=1;
while(!Q.empty()){
int x=Q.front();Q.pop();
for(int i=0;i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if(!vis[e.to]&&e.cap>e.flow){
vis[e.to]=1;
dist[e.to]=dist[x]+1;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x,int a){
if(x==t||a==0)return a;
int flow=0,f;
for(int& i=cur[x];i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if(dist[x]+1==dist[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){
e.flow+=f;
edges[G[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0)break;
}
}
return flow;
}
int Maxflow(int s,int t){
this->s=s;this->t=t;
int flow=0;
while(BFS()){
memset(cur,0,sizeof(cur));
flow+=DFS(s,INF);
flow+=DFS(s,INF);
}
return flow;
}
void init(){
edges.clear();
for(int i=0;i<maxn;i++){
G[i].clear();
dist[i]=0;
}
}
}Do;
int main()
{
int N,M,T,cns=1,tp,sp;
scanf("%d",&T);
while(T--)
{
Do.init();
int sum=0;
scanf("%d%d",&N,&M);
int Max=-1;
sp=0;
for(int i=1;i<=N;i++)
{
int p,s,e;
scanf("%d%d%d",&p,&s,&e);
Max=max(Max,e);
sum+=p;
Do.AddEdge(sp,i,p);
for(int j=s;j<=e;j++)
{
Do.AddEdge(i,N+j,1);
}
}
tp=N+Max+1;
for(int i=N+1;i<N+Max;i++)
{
Do.AddEdge(i,tp,M);
}
if(sum==Do.Maxflow(0,tp))
cout<<"Case "<<cns++<<": "<<"Yes"<<endl;
else
cout<<"Case "<<cns++<<": "<<"No"<<endl;
cout<<endl;
}
}
hdu 3081
#include<iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 205;
bool bmap[maxn][maxn];
bool bmask[maxn];
int nx,ny;
int cx[maxn];
int cy[maxn];
int fa[maxn];
int getfa(int x)
{
if(fa[x]!=x)
fa[x]=getfa(fa[x]);
return fa[x];
}
int findpath(int u )
{
int i;
for(i=1; i<=ny; i++)
{
if(bmap[u][i] && ! bmask[i])
{
bmask[i] = 1;
if(cy[i] == -1 || findpath(cy[i]))
{
cy[i] = u;
cx[u] = i;
return 1;
}
}
}
return 0;
}
int maxmatch()
{
int res(0);
int i,j;
for(i=1; i<=nx; i++)
{
cx[i]=-1;
}
for(j=1; j<=ny; j++)
{
cy[j]=-1;
}
for( i = 1; i <= nx ; i++ )
{
if ( cx [ i ] == -1)
{
for(j = 1; j <= ny ; j++ )
{
bmask[j] = 0;
}
res+=findpath(i);
}
}
return res;
}
int main()
{
int sz;
scanf("%d",&sz);
while(sz--)
{
int n,m,f,a,b;
scanf("%d%d%d",&n,&m,&f);
nx=ny=n;
for(int j=0; j<=nx; j++)
{
for(int k=0; k<=ny; k++)
{
bmap[j][k]=0;
}
}
for(int i=0;i<=n;i++)
{
fa[i]=i;
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
bmap[a][b]=1;
}
for(int i=0;i<f;i++)
{
scanf("%d%d",&a,&b);
int A=getfa(a);
int B=getfa(b);
if(A!=B)
{
fa[A]=B;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(getfa(i)==getfa(j))
{
for(int k=1;k<=n;k++)
{
if(bmap[i][k]==1||bmap[j][k]==1)
bmap[i][k]=bmap[j][k]=1;
}
}
}
}
int ans;
for(ans=0;ans<=n;)
{
int res=maxmatch();
if(res==n)
{
ans++;
for(int i=1;i<=n;i++)
{
bmap[i][cx[i]]=0;
}
}
else
break;
}
cout<<ans<<endl;
}
}
hdu 1533
/*
1.WA 关于二分图匹配的数据范围要注意是否要乘以2 切记
* 考虑范围要考虑反向边
*/
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <queue>
#define oo 0x13131313
using namespace std;
const int MAXN=400;
const int MAXM=200000;
const int INF=0x3f3f3f3f;
struct Edge
{
int to,next,cap,flow,cost;
void get(int a,int b,int c,int d)
{
to=a,cap=b,cost=c;next=d;flow=0;
}
}edge[MAXM];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N;
void init(int n)
{
N=n;
tol=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int cap,int cost)
{
edge[tol].get(v,cap,cost,head[u]);head[u]=tol++;
edge[tol].get(u,0,-cost,head[v]);head[v]=tol++;
}
bool spfa(int s,int t)
{
queue<int>q;
for(int i=0;i<N;i++)
{
dis[i]=INF;
vis[i]=false;
pre[i]=-1;
}
dis[s]=0;
vis[s]=true;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=false;
for(int i= head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].cap>edge[i].flow&&
dis[v]>dis[u]+edge[i].cost )
{
dis[v]=dis[u]+edge[i].cost;
pre[v]=i;
if(!vis[v])
{
vis[v]=true;
q.push(v);
}
}
}
}
if(pre[t]==-1) return false;
else return true;
}
int minCostMaxflow(int s,int t,int &cost)
{
int flow=0;
cost = 0;
while(spfa(s,t))
{
int Min=INF;
for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
{
if(Min >edge[i].cap-edge[i].flow)
Min=edge[i].cap-edge[i].flow;
}
for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
{
edge[i].flow+=Min;
edge[i^1].flow-=Min;
cost+=edge[i].cost*Min;
}
flow+=Min;
}
return flow;
}
struct Home
{
int x,y;
}H[MAXN],P[MAXN];
int totH,totP;
int NN,MM;
void input()
{
char c;
totH=0;totP=0;
for(int i=1;i<=NN;i++)
{
for(int j=1;j<=MM;j++)
{
scanf("%c",&c);
if(c=='H') totH++,H[totH].x=i,H[totH].y=j;
else if(c=='m') totP++,P[totP].x=i,P[totP].y=j;
}
getchar();
}
}
void CreatGraph()
{
int ANS=0;
int NNN=totP+totH;//該题选择NNN+1为起点,NNN+2为终点,其实大部分时候选择0为起点
for(int i=1;i<=totP;i++)
for(int j=1;j<=totH;j++)
{
int t=abs(P[i].x-H[j].x)+abs(P[i].y-H[j].y);
addedge(i,j+totP,1,t);
}
for(int i=1;i<=totP;i++)
addedge(NNN+1,i,1,0);
for(int i=totP+1;i<=NNN;i++)
addedge(i,NNN+2,1,0);
minCostMaxflow(NNN+1,NNN+2,ANS);
printf("%d\n",ANS);
}
int main()
{
while(cin>>NN>>MM&&NN&&MM)
{
getchar();
init(MAXN);
input();
CreatGraph();
}
return 0;
}
hdu 3667
/*
1.WA 关于二分图匹配的数据范围要注意是否要乘以2 切记
* 考虑范围要考虑反向边
*/
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <queue>
#define oo 0x13131313
using namespace std;
const int MAXN=400;
const int MAXM=200000;
const int INF=0x3f3f3f3f;
struct Edge
{
int to,next,cap,flow,cost;
void get(int a,int b,int c,int d)
{
to=a,cap=b,cost=c;next=d;flow=0;
}
}edge[MAXM];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N;
void init(int n)
{
N=n;
tol=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int cap,int cost)
{
edge[tol].get(v,cap,cost,head[u]);head[u]=tol++;
edge[tol].get(u,0,-cost,head[v]);head[v]=tol++;
}
bool spfa(int s,int t)
{
queue<int>q;
for(int i=0;i<N;i++)
{
dis[i]=INF;
vis[i]=false;
pre[i]=-1;
}
dis[s]=0;
vis[s]=true;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=false;
for(int i= head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].cap>edge[i].flow&&
dis[v]>dis[u]+edge[i].cost )
{
dis[v]=dis[u]+edge[i].cost;
pre[v]=i;
if(!vis[v])
{
vis[v]=true;
q.push(v);
}
}
}
}
if(pre[t]==-1) return false;
else return true;
}
int minCostMaxflow(int s,int t,int &cost)
{
int flow=0;
cost = 0;
while(spfa(s,t))
{
int Min=INF;
for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
{
if(Min >edge[i].cap-edge[i].flow)
Min=edge[i].cap-edge[i].flow;
}
for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
{
edge[i].flow+=Min;
edge[i^1].flow-=Min;
cost+=edge[i].cost*Min;
}
flow+=Min;
}
return flow;
}
struct Home
{
int x,y;
}H[MAXN],P[MAXN];
int totH,totP;
int NN,MM;
void input()
{
char c;
totH=0;totP=0;
for(int i=1;i<=NN;i++)
{
for(int j=1;j<=MM;j++)
{
scanf("%c",&c);
if(c=='H') totH++,H[totH].x=i,H[totH].y=j;
else if(c=='m') totP++,P[totP].x=i,P[totP].y=j;
}
getchar();
}
}
void CreatGraph()
{
int ANS=0;
int NNN=totP+totH;//該题选择NNN+1为起点,NNN+2为终点,其实大部分时候选择0为起点
for(int i=1;i<=totP;i++)
for(int j=1;j<=totH;j++)
{
int t=abs(P[i].x-H[j].x)+abs(P[i].y-H[j].y);
addedge(i,j+totP,1,t);
}
for(int i=1;i<=totP;i++)
addedge(NNN+1,i,1,0);
for(int i=totP+1;i<=NNN;i++)
addedge(i,NNN+2,1,0);
minCostMaxflow(NNN+1,NNN+2,ANS);
printf("%d\n",ANS);
}
int main()
{
while(cin>>NN>>MM&&NN&&MM)
{
getchar();
init(MAXN);
input();
CreatGraph();
}
return 0;
}
hdu 2255
//网络流做法,会超时
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int INF=0x7FFFFFFF;
const int maxn=610;
struct Edge
{
int from,to,cap,flow,cost;
};
int N,M,K,len,s,t;
vector<Edge> edges;
vector<int> G[maxn];
int inq[maxn];
int d[maxn];
int p[maxn];
int a[maxn];
void init()
{
for(int i=0; i<maxn; i++) G[i].clear();
edges.clear();
}
void Addedge(int from,int to,int cap,int cost)
{
edges.push_back((Edge)
{
from,to,cap,0,cost
});
edges.push_back((Edge)
{
to,from,0,0,-cost
});
len=edges.size();
G[from].push_back(len-2);
G[to].push_back(len-1);
}
bool BellmanFord(int s,int t,int &flow,int &cost)
{
for(int i=0; i<maxn; i++) d[i]=INF;
memset(inq,0,sizeof(inq));
memset(p,-1,sizeof(p));
d[s]=0;
inq[s]=1;
p[s]=0;
a[s]=INF;
queue<int>Q;
Q.push(s);
while(!Q.empty())
{
int u=Q.front();
Q.pop();
inq[u]=0;
for(int i=0; i<G[u].size(); i++)
{
Edge& e=edges[G[u][i]];
if(e.cap>e.flow&&d[e.to]>d[u]+e.cost)
{
d[e.to]=d[u]+e.cost;
p[e.to]=G[u][i];
a[e.to]=min(a[u],e.cap-e.flow);
if(!inq[e.to])
{
Q.push(e.to);
inq[e.to]=1;
}
}
}
}
if(d[t]==INF) return false;
flow+=a[t];
cost+=d[t]*a[t];
int u=t;
while(u!=s)
{
edges[p[u]].flow+=a[t];
edges[p[u]^1].flow-=a[t];
u=edges[p[u]].from;
}
return true;
}
void Mincost (int s,int t)
{
int flow=0,cost=0;
while(BellmanFord(s,t,flow,cost));
printf("%d\n",-cost);
}
int NN,MM;
void input()
{
for(int i=1;i<=NN;i++)
{
int x;
for(int j=NN+1;j<=NN*2;j++)
{
scanf("%d",&x);
Addedge(i,j,1,-x);
}
}
int ans=0;
int st=0,sd=NN*2+1;
for(int i=1;i<=NN;i++)
{
Addedge(st,i,1,0);
}
for(int i=1+NN;i<=NN*2;i++)
{
Addedge(i,sd,1,0);
}
Mincost(st,sd);
}
int main()
{
while(scanf("%d",&NN)!=EOF)
{
init();
input();
}
}
hdu 5644
/*
1.WA 关于二分图匹配的数据范围要注意是否要乘以2 切记
* 考虑范围要考虑反向边
*/
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <queue>
#define oo 0x13131313
using namespace std;
const int MAXN=405;
const int MAXM=400010;
const int INF=0x3f3f3f3f;
struct Edge
{
int to,next,cap,flow,cost;
void get(int a,int b,int c,int d)
{
to=a,cap=b,cost=c;next=d;flow=0;
}
}edge[MAXM];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N;
void init(int n)
{
N=n;
tol=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int cap,int cost)
{
edge[tol].get(v,cap,cost,head[u]);head[u]=tol++;
edge[tol].get(u,0,-cost,head[v]);head[v]=tol++;
}
bool spfa(int s,int t)
{
queue<int>q;
for(int i=0;i<=N;i++)
{
dis[i]=INF;
vis[i]=false;
pre[i]=-1;
}
dis[s]=0;
vis[s]=true;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=false;
for(int i= head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].cap>edge[i].flow&&
dis[v]>dis[u]+edge[i].cost )
{
dis[v]=dis[u]+edge[i].cost;
pre[v]=i;
if(!vis[v])
{
vis[v]=true;
q.push(v);
}
}
}
}
if(pre[t]==-1) return false;
else return true;
}
int minCostMaxflow(int s,int t,int &cost)
{
int flow=0;
cost = 0;
while(spfa(s,t))
{
int Min=INF;
for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
{
if(Min >edge[i].cap-edge[i].flow)
Min=edge[i].cap-edge[i].flow;
}
for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
{
edge[i].flow+=Min;
edge[i^1].flow-=Min;
cost+=edge[i].cost*Min;
}
flow+=Min;
}
return flow;
}
int n,k;
int p[402];
int s[402],t[402];
int m,P,q;
void input()
{
int sum=0;
int ans=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&p[i]);
sum+=p[i];
}
scanf("%d%d%d",&m,&P,&q);
int st=0,sd=n*2+1;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&s[i],&t[i]);
for(int j=1;j<=n;j++)
{
if(j+n+t[i]<=n*2)
addedge(j,j+n+t[i],INF,s[i]);
}
}
for(int i=1;i<=n;i++)
{
addedge(st,i,p[i],0);
}
for(int i=n+1;i<=2*n;i++)
{
addedge(i,sd,p[i-n],0);
}
addedge(st,n+1,k,0);
for(int i=P+n;i<=2*n;i++)
{
addedge(st,i,INF,q);
}
for(int i=1;i<n;i++)
{
addedge(i,i+1,INF,0);
addedge(i+n,i+n+1,INF,0);
}
if(minCostMaxflow(st,sd,ans)==sum)
cout<<ans<<endl;
else
cout<<"No solution"<<endl;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init(MAXN);
input();
}
return 0;
}
zoj 3933
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int INF=0x7FFFFFFF;
const int maxn=510;
struct Edge
{
int from,to,cap,flow,cost;
};
int N,M,K,len,s,t;
vector<Edge> edges;
vector<int> G[maxn];
int inq[maxn];
int d[maxn];
int p[maxn];
int a[maxn];
int zh[maxn][maxn];
char a1[510],a2[510];
void init()
{
for(int i=0; i<maxn; i++) G[i].clear();
edges.clear();
}
void Addedge(int from,int to,int cap,int cost)
{
edges.push_back((Edge)
{
from,to,cap,0,cost
});
edges.push_back((Edge)
{
to,from,0,0,-cost
});
len=edges.size();
G[from].push_back(len-2);
G[to].push_back(len-1);
}
bool BellmanFord(int s,int t,int &flow,int &cost)
{
for(int i=0; i<maxn; i++) d[i]=INF;
memset(inq,0,sizeof(inq));
memset(p,-1,sizeof(p));
d[s]=0;
inq[s]=1;
p[s]=0;
a[s]=INF;
queue<int>Q;
Q.push(s);
while(!Q.empty())
{
int u=Q.front();
Q.pop();
inq[u]=0;
for(int i=0; i<G[u].size(); i++)
{
Edge& e=edges[G[u][i]];
if(e.cap>e.flow&&d[e.to]>d[u]+e.cost)
{
d[e.to]=d[u]+e.cost;
p[e.to]=G[u][i];
a[e.to]=min(a[u],e.cap-e.flow);
if(!inq[e.to])
{
Q.push(e.to);
inq[e.to]=1;
}
}
}
}
if(d[t]==INF) return false;
flow+=a[t];
cost+=d[t]*a[t];
int u=t;
while(u!=s)
{
edges[p[u]].flow+=a[t];
edges[p[u]^1].flow-=a[t];
u=edges[p[u]].from;
}
return true;
}
void Mincost (int s,int t)
{
int flow=0,cost=0;
while(BellmanFord(s,t,flow,cost));
printf("%d ",flow);
printf("%d\n",-cost);
}
int NN;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d",&NN);
scanf(" %s",a1);
scanf(" %s",a2);
memset(zh,0,sizeof(zh));
for(int i=0;i<NN;i++)
{
int m;
scanf("%d",&m);
for(int j=0;j<m;j++)
{
int x;
scanf("%d",&x);
zh[i][x-1]=zh[x-1][i]=1;
}
}
int st=NN,sd=NN+1;
for(int i=0;i<NN;i++)
{
if(a1[i]=='0')
{Addedge(st,i,1,0);
for(int j=0;j<NN;j++)
{
if(zh[i][j]==0&&zh[j][i]==0&&a1[j]=='1')
{
if(a2[i]=='0'&&a2[j]=='0')
{
Addedge(i,j,1,-2);
}
else if(a2[i]=='0'&&a2[j]=='1')
Addedge(i,j,1,-1);
else if(a2[i]=='1'&&a2[j]=='0')
Addedge(i,j,1,-1);
else
Addedge(i,j,1,0);
}
}
}
}
for(int i=0;i<NN;i++)
{
if(a1[i]=='1')
Addedge(i,sd,1,0);
}
Mincost(st,sd);
int ss=edges.size();
for(int i=0;i<ss;i=i+2)
{
if(edges[i].from==st||edges[i].to==st||edges[i].from==sd||edges[i].to==sd)
continue;
if(edges[i].flow)
cout<<edges[i].to+1<<" "<<edges[i].from+1<<endl;
}
}
return 0;
}