一直觉得自己图论各种垃圾,而且dinic莫名其妙地各种玄学(虽然每次最后都证明确实要么是建图错了要么是哪儿哪儿错了)
bzoj 1433
这道题其实挺裸的。
源点向每个住校的学生连一条边,每个在校的学生向汇点连一条边,每个住校的学生向可以住的床连一条边(在校生且与他关系好),边的流量都是1.
(感觉自己太垃圾了这道弱智题居然调了好久,而且代码从沈阳码到成都23333)
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
const int N = 100010;
const int oo = 0x73f3f3f;
int t;
int n;
int cnt=0;
int num=1;
int head[N];
int s,tt;
int a[N],b[N];
inline int Min(int a,int b){
return a<b?a:b;
}
struct node{
int pre,v,f;
}edge[N];
void addedge(int from,int to,int f){
num++;
edge[num].pre=head[from];
edge[num].v=to;
edge[num].f=f;
head[from]=num;
num++;
edge[num].pre=head[to];
edge[num].v=from;
edge[num].f=0;
head[to]=num;
}
int dis[N],state[N];
bool vis[N];
bool bfs(){
int h=0,tail=1;
state[1]=s;vis[s]=true;
dis[s]=0;
do{
h++;
int u=state[h];
for(int i=head[u];i;i=edge[i].pre){
int v=edge[i].v;
if(!vis[v]&&edge[i].f){
tail++;
state[tail]=v;
dis[v]=dis[u]+1;
vis[v]=true;
}
}
}
while(h<tail);
if(vis[tt]) return true;
return false;
}
int dfs(int u,int delta){
if(u==tt||delta==0) return delta;
int ans=0;
for(int i=head[u];i&δi=edge[i].pre){
int v=edge[i].v;
if(dis[v]==dis[u]+1&&edge[i].f){
int dd=dfs(v,Min(delta,edge[i].f));
edge[i].f-=dd;
edge[i^1].f+=dd;
ans+=dd;
delta-=dd;
if(!delta) break;
}
}
if(!ans) dis[u]=-1;
return ans;
}
void zero(){
ms(state,0);ms(dis,0);ms(vis,0);
}
int Maxflow(){
int ans=0;
while(1){
zero();
if(!bfs()) break;
ans+=dfs(s,oo);
}
return ans;
}
void update(){
cnt=0,num=1;ms(a,0);ms(b,0);ms(head,0);
}
int main(){
scanf("%d",&t);
while(t--){
update();
scanf("%d",&n);
s=0,tt=n+n+1;
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
a[i]=x;
if(x==1) addedge(i+n,tt,1);//如果某个人是在校学生 向汇点连张床
else {addedge(s,i,1);cnt++;}//其他非在线学生 源点向其连线
}
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
b[i]=x;
if(a[i]==1&&x==0){//某个人是在校学生 并且留校
cnt++;
addedge(i,n+i,1);//他和自己的床连
addedge(s,i,1);}//源点和他自己连
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int x;
scanf("%d",&x);
if(x==1&&a[i]==0||x==1&&a[i]==1&&b[i]==0){//如果某两个人关系好并且住校
if(a[j]) addedge(i,n+j,1);//他的朋友有床
}
}
}
// printf("%d ",cnt);
if(Maxflow()==cnt) printf("^_^\n");
else printf("T_T\n");
}
return 0;
}
poj 1459
这道题的输入太骚气了233333但其实题还好 随手写了个当前弧优化
【好久以前写的题了当时没有写题解也已经忘了23333】
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
const int N = 10010;
const int INF = 1<<30;
int n,np,nc,m;
int tot=1;
int head[N];
inline int Min(int a,int b){
return a<b?a:b;
}
struct node{
int pre,v,f;
}edge[N<<1];
void adde(int from,int to,int f){
tot++;
edge[tot].pre = head[from];
edge[tot].v = to;
edge[tot].f = f;
head[from] = tot;
tot++;
edge[tot].pre = head[to];
edge[tot].v = from;
edge[tot].f = 0;
head[to] = tot;
}
int dep[N],state[N*10];
bool vis[N];
int cur[N];
bool bfs(){
int h=0,tail=1;
dep[n]=0;
state[1]=n;vis[n]=true;
while(h<tail){
h++;
int u=state[h];
for(int i=head[u];i;i=edge[i].pre){
int v=edge[i].v;
if(!vis[v]&&edge[i].f){
dep[v]=dep[u]+1;
vis[v]=true;
tail++;
state[tail]=v;
}
}
}
if(vis[n+1]) return true;
return false;
}
int dfs(int u,int delta){
if(u==n+1||delta==0) return delta;
int ans=0;
for(int &i=cur[u];i&δi=edge[i].pre){
int v=edge[i].v;
if(edge[i].f&&dep[v]==dep[u]+1){
int dd=dfs(v,Min(delta,edge[i].f));
edge[i].f-=dd;
edge[i^1].f+=dd;
delta-=dd;
ans+=dd;
if(!delta) break;
}
}
if(!ans) dep[u]=-1;
return ans;
}
void zero(){
ms(dep,0);ms(state,0);ms(vis,0);ms(cur,0);
}
int maxflow(){
int ans=0;
while(1){
zero();
for(register int i=0;i<=n+1;i++) cur[i]=head[i];
if(!bfs()) break;
ans+=dfs(n,INF);
}
return ans;
}
void update(){
ms(head,0);ms(edge,0);
tot=1;
}
int main(){
while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF){
// scanf("%d%d%d%d",&n,&np,&nc,&m);
update();
char ch;
while(m--){
int u,v,w;
/*char ch=getchar();
while(ch!='(')
ch=getchar();
scanf("%d,%d)%d",&u,&v,&w);//这骚气的输入*/
cin>>ch>>u>>ch>>v>>ch>>w;
if(u==v) continue;
adde(u,v,w);
}
for(int i=1;i<=np;i++){
int u,f;
/*char ch=getchar();
while(ch!='(')
ch=getchar();
scanf("%d)%d",&u,&f);*/
cin>>ch>>u>>ch>>f;
adde(n,u,f);
}
for(int i=1;i<=nc;i++){
int u,f;
/*char ch=getchar();
while(ch!='(')
ch=getchar();
scanf("%d)%d",&u,&f);*/
cin>>ch>>u>>ch>>f;
adde(u,n+1,f);
}
printf("%d\n",maxflow());
}
return 0;
}