SPOJ_839_OPTM

/*
*NAME: OPTM
*LANG: C++
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#define INF 0x7FFFFFFF
using namespace std;

int tt,n,m,s,t,ans,edgeNum;
struct node{
int x,y;
int p[5001],pp[5001],ppp[5001];//p表示该节点数字，pp表示该节点剩余数字
struct edge_node{
int v,c,next;
}e[100000];//边集数组
int v[5000],d[5000],c[5000];//v储存边集，d储存深度，c储存该层节点数
bool cover[5001];

void insert(int a,int b,int c){
edgeNum++;
e[edgeNum].v=b;e[edgeNum].c=c;e[edgeNum].next=v[a];v[a]=edgeNum;
edgeNum++;
e[edgeNum].v=a;e[edgeNum].c=0;e[edgeNum].next=v[b];v[b]=edgeNum;
}
void graphInit(){
s=n+1;t=n+2;edgeNum=0;
memset(cover,false,sizeof(cover));
memset(v,0,sizeof(v));
memset(d,0,sizeof(d));
memset(c,0,sizeof(c));
memset(e,0,sizeof(e));
}
void graphMake(){
for (int i=1;i<=n;++i)
if (p[i]==-1)
insert(s,i,1),insert(i,t,1);
else{
int tmp = pp[i] % 2;pp[i]/=2;
tmp==1?insert(s,i,INF):insert(i,t,INF);
}
for (int i=1;i<=m;++i)
}
void update(int len,int pos){
cover[pos]=true;
int tmp=v[pos];
while (tmp>0){
if (!cover[e[tmp].v] && e[tmp].c>0){
if (p[e[tmp].v]==-1)
ppp[e[tmp].v]+=pow(2,len);
update(len,e[tmp].v);
}
tmp=e[tmp].next;
}
}
int opp(int x){
return (x%2==1)?x+1:x-1;
}
int maxflow(int x,int lim){
int ret,min_num,i,j,max_flow;
if (x==t) return lim;
max_flow=0;min_num=t;
j=v[x];
while (j!=0){
if (e[j].c>0){
if (d[e[j].v]+1==d[x]){
ret=min(lim,e[j].c);
ret=maxflow(e[j].v,ret);
e[j].c-=ret;e[opp(j)].c+=ret;
lim-=ret;max_flow+=ret;
if (d[s]>=t) return max_flow;
}
min_num=min(min_num,d[e[j].v]+1);
}
j=e[j].next;
}
if (d[x]==min_num) return max_flow;
--c[d[x]];
if (c[d[x]]==0) d[s]=t;
d[x]=min_num;++c[d[x]];
return max_flow;
}
void init(){
int know;scanf("%d",&know);memset(p,0,sizeof(p));
for (int i=0,a,b;i<know;++i){scanf("%d %d",&a,&b);p[a]=b;}
for (int i=1;i<=n;++i) {ppp[i]=pp[i]=p[i];if (!p[i]) p[i]-=1;}
}
void print(){
for (int i=1;i<=n;++i)
printf("%d\n",ppp[i]);
}
int main(){
scanf("%d",&tt);
for (int k=1;k<=tt;++k){
init();
//solve
for (int i=0;i<=31;++i){
//makeGraph
graphInit();
graphMake();
//get minCut
c[0]=n+2;ans=0;
while (d[s]<t) ans+=maxflow(s,INF);
//update
update(i,s);
}
print();
}
return 0;
}

• 本文已收录于以下专栏：

举报原因： 您举报文章：SPOJ_839_OPTM 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)