P2756
題意:
思路:
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
inline int read(){
int X = 0,w = 0;char ch = 0;
while(!isdigit(ch)) {w |= ch == '-';ch = getchar();}
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48),ch = getchar();
return w ? -X : X;
}
const int N = 250;
const int inf = 0x3f3f3f3f;
struct Edge{
int to,nex,w;
}e[N*N];
int head[N],idx = 1,dep[N];
void add_edge(int u,int v,int w){
e[++idx].to = v;
e[idx].w = w;
e[idx].nex = head[u];
head[u] = idx;
}
int n,m,S,T;
bool bfs(){
memset(dep,0,sizeof(dep));
dep[S] = 1;
queue<int> q;
q.push(S);
while(q.size()){
int u = q.front();q.pop();
for(int i = head[u];~i;i = e[i].nex){
int v = e[i].to,w = e[i].w;
if(w && !dep[v]){
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[T];
}
int dfs(int u,int flow){
if(u == T) return flow;
int sum = 0;
for(int i = head[u];~i;i = e[i].nex){
int v = e[i].to,w = e[i].w;
if(w && dep[v] == dep[u] + 1){
int t = dfs(v,min(flow,w));
flow -= t,sum += t;
e[i].w -= t,e[i^1].w += t;
}
}
if(!sum) dep[u] = 0;
return sum;
}
int main(){
memset(head,-1,sizeof(head));
scanf("%d%d",&m,&n);
S = n + 1,T = n + 2;//將源點設爲n+1,匯點設爲n+2
int u,v;
while(1){
u = read(),v = read();
if(u == -1) break;
add_edge(u,v,1),add_edge(v,u,0);
}
for(int i = 1;i <= m;i++){
add_edge(S,i,1),add_edge(i,S,0);
}
for(int i = m + 1;i <= n;i++){
add_edge(i,T,1),add_edge(T,i,0);
}
int ans = 0;
while(bfs()) ans += dfs(S,inf);
printf("%d\n",ans);
for(int i = 2;i <= idx;i+=2){
if(e[i].to != S&&e[i^1].to != S)
if(e[i].to != T&&e[i^1].to != T)
if(e[i^1].w != 0){
printf("%d %d\n",e[i^1].to,e[i].to);
}
}
return 0;
}
P4014
題意:
思路:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;
inline int read(){
int X = 0,w = 0;char ch = 0;
while(!isdigit(ch)) {w |= ch == '-';ch = getchar();}
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48),ch = getchar();
return w ? -X : X;
}
const int N = 210,inf = 0x3f3f3f3f;
int n,head[N],dist[N];
int q[N*100],l,r;
int idx,S,T;
int maxflow = 0,mincost = 0;
int mp[N][N];
bool vis[N];
struct node{
int to,nex,w,cost;
}e[N*N*2];
inline void add(int u,int v,int w,int c) {
++idx;
e[idx].to=v;e[idx].w=w;e[idx].cost=c;e[idx].nex=head[u];head[u]=idx;
++idx;
e[idx].to=u;e[idx].w=0;e[idx].cost=-c;e[idx].nex=head[v];head[v]=idx;
}
bool spfa(){
memset(vis,0,sizeof(vis));
memset(dist,0x3f,sizeof(dist));
l = 1;r = 0;
queue<int> q;q.push(S);
dist[S]=0; vis[S]=1;
while (q.size()) {
int u = q.front();q.pop();
vis[u] = 0;
for (int i = head[u];~i;i = e[i].nex) {
int v = e[i].to;
if (e[i].w && dist[v]>dist[u]+e[i].cost) {
dist[v] = dist[u]+e[i].cost;
if (!vis[v]) {
vis[v] = 1;
q.push(v);
}
}
}
}
return dist[T] < inf;
}
int dfs(int u,int flow) {
if (u == T) {
vis[T]=1;
maxflow += flow;
return flow;
}
int goflow = 0,used = 0;
vis[u]=1;
for (int i = head[u];~i;i = e[i].nex) {
int v = e[i].to;
if ((!vis[v] || v == T) && e[i].w && dist[v]==dist[u]+e[i].cost) {
goflow = dfs(v,min(flow-used,e[i].w));
if (!goflow) continue;
used += goflow;
e[i].w -= goflow;
e[i^1].w += goflow;
mincost += goflow*e[i].cost;
if (used == flow) break;
}
}
return used;
}
void MCMF(){
while (spfa()) {
vis[T]=1;
while (vis[T]) {
memset(vis,0,sizeof(vis));
dfs(S,inf);
}
}
}
int a=0;
int main(){
memset(head,-1,sizeof(head));idx = 1;
n = read();
S = 0;
T = 2*n+1;
for (int i = 1;i <= n;++i) {
add(S,i,1,0);
add(i+n,T,1,0);
for (int j = 1;j <= n;++j) {
mp[i][j] = read();
add(i,j+n,1,-mp[i][j]);
}
}
MCMF();
int mx = -mincost;
mincost = maxflow = 0;
idx = 1;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
for (int i = 1;i <= n;++i) {
add(S,i,1,0);
add(i+n,T,1,0);
for (int j = 1;j <= n;++j) {
add(i,j+n,1,mp[i][j]);
}
}
MCMF();
printf("%d\n%d\n",mincost,mx);
return 0;
}