321B

MCMF必须是满足流量最大为前提下的最小费用流(这里是最大费用流)
因此还必须不断地枚举m的流量才行

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 1e5+11;
const int oo = 0x3f3f3f3f;
int to[maxn<<1],cost[maxn<<1],cap[maxn<<1],flow[maxn<<1],nxt[maxn<<1];
int head[maxn],tot;
void init(){
    memset(head,-1,sizeof head);
    tot=0;
}
void add(int u,int v,int c,int w){
    to[tot]=v;
    cap[tot]=c;
    flow[tot]=0;
    cost[tot]=w;
    nxt[tot]=head[u];
    head[u]=tot++;
    swap(u,v);
    to[tot]=v;
    cap[tot]=0;
    flow[tot]=0;
    cost[tot]=-w;
    nxt[tot]=head[u];
    head[u]=tot++;
}
struct QUEUE{
    int que[maxn];
    int front,rear;
    void init(){front=rear=0;}
    void push(int x){que[rear++]=x;}
    int pop(){return que[front++];}
    bool empty(){return front==rear;}
}que;
int n,m,s,t;
int dis[maxn],pre[maxn];
bool vis[maxn];
bool spfa(){
	que.init();
	memset(dis,0x80,sizeof dis);
	memset(vis,0,sizeof vis);
	memset(pre,-1,sizeof pre);
	que.push(s);dis[s]=0;vis[s]=1;
	while(!que.empty()){
		int u = que.pop();
		vis[u]=0;
		for(int i = head[u]; ~i; i = nxt[i]){
			int v=to[i],c=cap[i],f=flow[i],w=cost[i];
			if(c>f&&dis[v]<dis[u]+w){
				dis[v]=dis[u]+w;
				pre[v]=i;
				if(!vis[v]){
					vis[v]=1;
					que.push(v);
				}
			}
		}
	}
	if(pre[t]==-1)return 0;
	return 1;
}
int mcmf(){
	int mc=0,mf=0;
	while(spfa()){
		int mn=oo;
		for(int i = pre[t]; ~i; i = pre[to[i^1]]){
			mn=min(mn,cap[i]-flow[i]);
		}
		for(int i = pre[t]; ~i; i = pre[to[i^1]]){
			flow[i]+=mn;
			flow[i^1]-=mn;
			mc+=cost[i]*mn;
		}
		mf+=mn;
	}
	return mc;
}
int n1,n2,n3,a[maxn],b[maxn],atr[maxn],x;
char str[199];
int main(){
	while(scanf("%d%d",&n1,&n2)!=EOF){
		init();
		if(n1<n2){
			n3=n2-n1;
			n=2*n2+2;
			t=n;s=t-1;
		}
		else{
			n3=0;
			n=n1+n2+2;
			t=n;s=n-1;	
		}
		for(int i = 1; i <= n1; i++){
			scanf("%s%d",str,&a[i]); 
			if(str[0]=='A') atr[i]=1;
			else atr[i]=0;
		}
		for(int i = 1; i <= n2; i++){
			scanf("%d",&b[i]);
		}
		if(n3) for(int i = 1; i <= n3; i++){
			atr[i+n1]=1;
			a[i+n1]=0;
		}
		for(int i = 1; i <= n2; i++){
			add(s,i,1,0);
		}
		for(int i = 1; i <= n1+n3; i++){
			add(i+n2,t,1,0);
		}
		for(int i = 1; i <= n2; i++){
			for(int j = 1; j <= n1+n3; j++){
				if(atr[j]==1){
					if(b[i]>=a[j]){
						if(a[j]!=-oo) add(i,j+n2,1,b[i]-a[j]);
						else add(i,j+n2,1,b[i]);
					}
					else add(i,j+n2,1,-9999);
				}
				else{
					if(b[i]>a[j]){
						add(i,j+n2,1,0);
					}
					else add(i,j+n2,1,-9999);
				}
			}
		} 
		printf("%d\n",mcmf());
	}
    return 0;
}
#include <bits/stdc++.h>



#define inf 0x3f3f3f3f

#define INF 0x3f3f3f3f3f3f3f3fLL

#define mod 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define sz(a) ((int)a.size())

#define x first

#define y second

#define eps 1e-8

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define rands(n) (rand()%n+1)

#define rand0(n) (rands(n)-1)

#define Rands(n) ((INT)rand()*rand()%n+1)

#define Rand0(n) (Rands(n)-1)

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

#define rep(i, a, b) for(int i=a; i<b; i++)



using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<INT, INT> PII;

typedef pair<pii, int> ppi;

typedef double DO;



template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}



template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}



#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)

    #define lld "%I64d"

#else

    #define lld "%lld"

#endif



#define NN 400

#define MC 100000



int N, M, a[NN], b[NN], V, src, tar, mx, S, T;

int adj[NN][NN], cap[NN][NN], cost[NN][NN];

int dis[NN], q[NN*NN], qf, qb, pre[NN], C, deg[NN];

char s[NN][10];



void init() {

	memset(pre, -1, sizeof(pre));

	memset(deg, 0, sizeof(deg));

}

void add_edge(int u, int v, int w, int c) {

	adj[u][deg[u]++]=v;

	adj[v][deg[v]++]=u;

	cap[u][v]=w; cap[v][u]=0;

	cost[u][v]=c; cost[v][u]=-c;

}

int Mincost_Maxflow() {

	int ans=0, bot; C=0;

	while(1) {

		memset(dis, 0x3f, sizeof(dis));

		qf=qb=0;

		dis[src]=0; q[qb++]=src;

		while(qf<qb) {

			int u=q[qf++];

			for(int i=0; i<deg[u]; i++) {

				int v=adj[u][i];

				if(cap[u][v]==0) continue;

				if(dis[v]>dis[u]+cost[u][v]) {

					dis[v]=dis[u]+cost[u][v];

					q[qb++]=v;

					pre[v]=u;

				}

			}

		}

		if(dis[tar]>=inf) return ans;

		bot=inf;

		for(int u=tar; u!=src; u=pre[u]) bot=min(bot, cap[pre[u]][u]);

		ans+=bot;

		for(int u=tar; u!=src; u=pre[u]){

			cap[pre[u]][u]-=bot;

			cap[u][pre[u]]+=bot;

		}

		C+=dis[tar]*bot;

	}

	return ans;

}

int main() {
	gn(N); gn(M);
	for(int i=1; i<=N; i++) {
		scanf("%s", s[i]);  gn(a[i]);
	}
	for(int i=1; i<=M; i++)  gn(b[i]);
	src=0; tar=M+N+1; S=M+N+2; T=M+N+3;
	for(int k=1; k<=M; k++) {
		init();
		add_edge(src, S, k, 0);
		for(int i=1; i<=M; i++) {
			add_edge(S, i, 1, 0);
			add_edge(i, T, 1, -b[i]);
			for(int j=1; j<=N; j++) {
				if(b[i]>=a[j] && s[j][0]=='A') add_edge(i, j+M, 1, a[j]-b[i]);
				else if(b[i]>a[j] && s[j][0]=='D') add_edge(i, j+M, 1, 0);
			}
		}
		for(int i=1; i<=N; i++) add_edge(M+i, tar, 1, 0);
		add_edge(T, tar, M, MC);
		Mincost_Maxflow();
		if(cap[tar][T]>max(0, k-N)) continue;
		mx= max(mx, -C+cap[tar][T]*MC);
	}
	printf("%d\n", mx);
	return 0;
}
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
typedef long long ll;
using namespace std;
const int maxn = 7e4+11;
const int oo = 0x3f3f3f3f;
int to[maxn<<1],cost[maxn<<1],cap[maxn<<1],flow[maxn<<1],nxt[maxn<<1];
int _to[maxn<<1],_cost[maxn<<1],_cap[maxn<<1],_flow[maxn<<1],_nxt[maxn<<2];
int head[maxn],tot;
int _head[maxn],_tot;
void init(){
    memset(head,-1,sizeof head);
    tot=0;
}
void add(int u,int v,int c,int w){
    to[tot]=v;
    cap[tot]=c;
    flow[tot]=0;
    cost[tot]=w;
    nxt[tot]=head[u];
    head[u]=tot++;
    swap(u,v);
    to[tot]=v;
    cap[tot]=0;
    flow[tot]=0;
    cost[tot]=-w;
    nxt[tot]=head[u];
    head[u]=tot++;
}
struct QUEUE{
    int que[maxn];
    int front,rear;
    void init(){front=rear=0;}
    void push(int x){que[rear++]=x;}
    int pop(){return que[front++];}
    bool empty(){return front==rear;}
}que;
int n,m,s,t;
int dis[maxn],pre[maxn];
bool vis[maxn];
bool spfa(){
	que.init();
	memset(dis,oo,sizeof dis);
	memset(vis,0,sizeof vis);
	memset(pre,-1,sizeof pre);
	que.push(s);dis[s]=0;vis[s]=1;
	while(!que.empty()){
		int u = que.pop();
		vis[u]=0;
		for(int i = head[u]; ~i; i = nxt[i]){
			int v=to[i],c=cap[i],f=flow[i],w=cost[i];
			if(c>f&&dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				pre[v]=i;
				if(!vis[v]){
					vis[v]=1;
					que.push(v);
				}
			}
		}
	}
	if(pre[t]==-1)return 0;
	return 1;
}
ll mcmf(){
	ll mc=0,mf=0;
	while(spfa()){
		int mn=oo;
		for(int i = pre[t]; ~i; i = pre[to[i^1]]){
			mn=min(mn,cap[i]-flow[i]);
		}
		for(int i = pre[t]; ~i; i = pre[to[i^1]]){
			flow[i]+=mn;
			flow[i^1]-=mn;
			mc+=1ll*cost[i]*mn;
		}
		mf+=mn;
	}
	return mc;
}
void backup(){
	memcpy(_to,to,sizeof to);
	memcpy(_nxt,nxt,sizeof nxt);
	memcpy(_cap,cap,sizeof cap);
	memcpy(_flow,flow,sizeof flow);
	memcpy(_cost,cost,sizeof cost);
	memcpy(_head,head,sizeof head);
	_tot=tot;
}
void recover(){
	memcpy(to,_to,sizeof to);
	memcpy(nxt,_nxt,sizeof nxt);
	memcpy(cap,_cap,sizeof cap);
	memcpy(flow,_flow,sizeof flow);
	memcpy(cost,_cost,sizeof cost);
	memcpy(head,_head,sizeof head);
	tot=_tot;
}
int n1,n2,n3,a[maxn],b[maxn],atr[maxn],x;
char str[199];
int main(){
	while(scanf("%d%d",&n1,&n2)!=EOF){
		init();int ss,tt;ll maxcost=oo;
		for(int i = 1; i <= n1; i++){
			scanf("%s%d",str,&a[i]);
			if(str[0]=='A') atr[i]=1;
			else atr[i]=0;
		}
		for(int i = 1; i <= n2; i++){
			scanf("%d",&b[i]);
		}
		n=n1+2*n2+4;t=n;s=t-1;tt=s-1;ss=tt-1;
		int guaidian=n2,duimian=n1+n2; 
		ll bigInt=200000;
		for(int i = 1; i <= n2; i++) add(ss,i,1,0);
		for(int i = 1; i <= n1; i++) add(i+duimian,tt,1,0);
		for(int i = 1; i <= n2; i++){
			add(i,i+guaidian,1,bigInt);
			add(i+guaidian,tt,1,-b[i]);
			for(int j = 1; j <= n1; j++){
				if(atr[j]==1) if(b[i]>=a[j])add(i,j+duimian,1,-(b[i]-a[j]));
				if(atr[j]==0) if(b[i]>a[j])add(i,j+duimian,1,0);
			} 
		}
		backup();
		for(int k = 1; k <= n2; k++){
//			if(k>1)break;
			recover();
			add(s,ss,k,0);
			add(tt,t,k,0);
			if(k<=n1) maxcost=min(maxcost,mcmf());
			else maxcost=min(maxcost,mcmf()+(k-n1)*bigInt);
		}
		maxcost=-maxcost;
		printf("%lld\n",maxcost); 
	}
	return 0;
	return 0;
}

510E

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring> 
#include<queue>
#include<vector>
#include<set>
using namespace std;
const int maxn = 1e5+11;
const int oo = 0x3f3f3f3f;
int to[maxn<<1],nxt[maxn<<1],cap[maxn<<1],flow[maxn<<1];
int head[maxn],tot;
struct UF{
	int p[256];
	void init(){
		for(int i = 0; i < 256; i++) p[i]=i;
	}
	int find(int x){
		return p[x]==x?x:p[x]=find(p[x]);
	}
	void link(int a,int b){
		a=find(a);b=find(b);
		if(a!=b) p[a]=b;
	}
}uf;
void init(){
    memset(head,-1,sizeof head);
    tot=0;
}
void add(int u,int v,int w){
    to[tot]=v;
    nxt[tot]=head[u];
    cap[tot]=w;
    flow[tot]=0;
    head[u]=tot++;
    swap(u,v);
    to[tot]=v;
    nxt[tot]=head[u];
    cap[tot]=0;
    flow[tot]=0;
    head[u]=tot++;
}
//int n,m,s,t;
//int dis[maxn],pre[maxn],cur[maxn],gap[maxn];
//bool vis[maxn];
struct QUEUE{
    int que[maxn];
    int front,rear;
    void init(){front=rear=0;}
    void push(int u){que[rear++]=u;}
    int pop(){return que[front++];}
    bool empty(){return front==rear;}
}que;
int n,m,s,t;
int gap[maxn],dep[maxn];
void bfs(){
	memset(dep,-1,sizeof dep);
	memset(gap,0,sizeof gap);
	gap[0]=1;
	que.init();
	que.push(t);dep[t]=0;
	while(!que.empty()){
		int u = que.pop();
		for(int i = head[u]; ~i; i = nxt[i]){
			int v=to[i];
			if(~dep[v])continue;
			que.push(v);
			dep[v]=dep[u]+1;
			gap[dep[v]]++;
		}
	}	
}
int cur[maxn],S[maxn];
int isap(){
	bfs();
	memcpy(cur,head,sizeof head);
	int ans=0,top=0,u=s;
	while(dep[s]<n){
		if(u==t){
			int mn=oo;
			int inser;
			for(int i = 0; i < top; i++){
				if(mn>cap[S[i]]-flow[S[i]]){
					mn=cap[S[i]]-flow[S[i]];
					inser=i;
				}
			}
			for(int i = 0; i < top; i++){
				flow[S[i]]+=mn;
				flow[S[i]^1]-=mn;
			}
			ans+=mn;
			top=inser;
			u=to[S[top]^1];
			continue;
		}
		bool flag=0;
		int v;
		for(int i = cur[u]; ~i; i = nxt[i]){
			v=to[i];
			if(cap[i]-flow[i]&&dep[v]+1==dep[u]){
				flag=1;
				cur[u]=i;
				break;
			}
		}
		if(flag){
			S[top++]=cur[u];
			u=v;
			continue;
		}
		int mn=n;
		for(int i = head[u]; ~i; i = nxt[i]){
			if(cap[i]-flow[i]&&dep[to[i]]<mn){
				mn=dep[to[i]];
				cur[u]=i;
			}
		}
		gap[dep[u]]--;
		if(!gap[dep[u]])return ans;
		dep[u]=mn+1;
		gap[dep[u]]++;
		if(u!=s)u=to[S[--top]^1];
	}
	return ans;
}
bool isnprime[maxn];
void sai(){
	isnprime[0]=isnprime[1]=1;
	for(int i = 2; i*i < 100000; i++){
		if(!isnprime[i]){
			for(int j = 2*i; j < 100000; j+=i){
				isnprime[j]=1;
			}
		}
	}
}
bool go[maxn];
vector<int> G[maxn];
int cnt;
vector<int> biao[500];
vector<int> biao2[500];
int biao3[maxn];
vector<int> biao4[maxn];
//void dfs(int u,int k){
//	go[u]=1;GG[k].push_back(u);
//	for(int i = 0; i < G[u].size(); i++){
//		if(!go[G[u][i]]) dfs(G[u][i],k);
//	}
//}
int n1,a[maxn];
bool in[maxn];

bool dfs(int now,int cur,int p,int one){
	if(cur==biao[now].size()+1){return 1;}
	if(cur==1){
		for(int i = 0; i < biao[now].size(); i++){
			in[biao[now][i]]=1; biao3[cur]=biao[now][i];
			bool flag=dfs(now,cur+1,biao[now][i],biao[now][i]);
			if(flag)return 1;
			in[biao[now][i]]=0;
		}
	}
	else{
		int qian=p;
		for(int i = 0; i < biao2[qian].size(); i++){
			if(cur!=biao[now].size()) {
				if(!isnprime[a[biao2[qian][i]]+a[one]])if(!isnprime[a[qian]+a[biao2[qian][i]]] && !in[biao2[qian][i]]){
					in[biao2[qian][i]]=1; biao3[cur]=biao2[qian][i];
					bool flag=dfs(now,cur+1,biao2[qian][i],one);
					if(flag)return 1;
					in[biao2[qian][i]]=0;
				}
			}
			else{
				if(!isnprime[a[qian]+a[biao2[qian][i]]] && !in[biao2[qian][i]]){
					in[biao2[qian][i]]=1; biao3[cur]=biao2[qian][i];
					bool flag=dfs(now,cur+1,biao2[qian][i],one);
					if(flag)return 1;
					in[biao2[qian][i]]=0;
				}
			} 
		}
	}
}
int main(){
	sai();
	while(scanf("%d",&n1)!=EOF){
		init(); 
		for(int i = 1; i <= n1; i++){
			scanf("%d",&a[i]);
		}
		n=n1+2;s=n-1;t=n;
		for(int i = 1; i <= n1; i++){
			if(a[i]&1) add(s,i,2);
			else add(i,t,2);
		}
		for(int i = 1; i <= n1; i++){
			if(a[i]&1) for(int j = 1; j <= n1; j++){
				if(!(a[j]&1)) if(!isnprime[a[i]+a[j]]) add(i,j,1);
			}
		}
		int ans=isap();
		if(ans!=n1){
			printf("Impossible\n");
			continue;
		}
		memset(G,0,sizeof G);
		for(int i = 1; i <= n1; i++){
			for(int j = head[i]; ~j; j = nxt[j]){
				int v=to[j],c=cap[j],f=flow[j];
				if(c==0||v==s||v==t) continue;
				if(f==1)G[i].push_back(v);
			}
		}
//		for(int i = 1; i <= n1; i++){
//			cout<<i<<": ";
//			if(G[i].size()==0) cout<<endl;
//			for(int j = 0; j < G[i].size(); j++){
//				if(j==G[i].size()-1) printf("%d\n",G[i][j]);
//				else printf("%d ",G[i][j]);
//			}
//		}
		
		uf.init();
		for(int i = 1; i <= n1; i++){
			for(int j = 0; j < G[i].size(); j++){
				uf.link(i,G[i][j]);
			}
		}
		for(int i = 1; i <= n1; i++) uf.find(i);
		cnt=0;
		memset(biao,0,sizeof biao);
		for(int i = 1; i <= n1; i++){
			if(uf.p[i]==i){
				cnt++;
			}
			biao[uf.p[i]].push_back(i);
		}
		printf("%d\n",cnt);
		int cnt2=0;
		memset(biao4,0,sizeof biao4);
		for(int i = 1; i <= n1; i++){
			if(biao[i].size()) printf("%d ",biao[i].size()),cnt2++;
			for(int j = 0; j < biao[i].size(); j++){
				biao4[cnt2].push_back(biao[i][j]);
//				if(j==biao[i].size()-1) printf("%d\n",biao[i][j]);
//				else printf("%d ",biao[i][j]);
			}
		}
		memcpy(biao,biao4,sizeof biao);
//		cout<<cnt2-cnt<<"ewe"<<endl;
		for(int i = 1; i <= cnt; i++){
			memset(biao2,0,sizeof biao2);
			for(int j = 0; j < biao[i].size(); j++){
				for(int k = 0; k < biao[i].size(); k++){
					if(j!=k) if(!isnprime[a[biao[i][j]]+a[biao[i][k]]]) biao2[biao[i][j]].push_back(biao[i][k]),cout<<a[biao[i][j]]<<" "<<a[biao[i][k]]<<endl;
				}
			}
			memset(biao3,0,sizeof biao3); memset(in,0,sizeof in);
			dfs(i,1,0,666);
			for(int j = 1; j <= biao[i].size(); j++){
				if(j==biao[i].size()) printf("%d\n",biao3[j]);
				else printf("%d ",biao3[j]);
			}
		}
	}
	return 0;
} 
posted @ 2017-11-26 15:13  Caturra  阅读(211)  评论(0)    收藏  举报