真他妈是道好题呀,刷新了我对并查集的认识。听说这题用网络流也能写,让我再去写发网络流,练练手。
并查集:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 40000
int n,m,ans,in,out;
int fa[500],f[500];
bool flag;
struct Edge{
int a,b,len;
}edge[MAXN];
int find(int x)
{
if(x!=fa[x])
fa[x]=find(fa[x]);
return fa[x];
}
bool cmp(Edge a,Edge b)
{
return a.len<b.len;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
int num=0;
memset(f,0,sizeof(f));
for(int i=0;i<n;i++)
{
scanf("%d",&in);
f[i+1]-=in;
}
for(int i=0;i<n;i++)
{
scanf("%d",&out);
f[i+1]+=out;
if(f[i+1]<0)num++;
}
scanf("%d",&m);
int a,b,c;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
edge[i].a=a;
edge[i].b=b;
edge[i].len=c;
}
sort(edge,edge+m,cmp);
int f1,f2;
for(int i=0;i<=n;i++)
fa[i]=i;
flag=false;
for(int i=0;i<m;i++)
{
f1=find(edge[i].a);
f2=find(edge[i].b);
if(f1!=f2)
{
fa[f1]=f2;
f[f2]+=f[f1];
if(f[f2]>=0)
{
if(f[f2]-f[f1]<0||f[f1]<0)
num--;
}
else if(f[f2]<0)
{
if(f[f2]-f[f1]<0&&f[f1]<0)
num--;
}
if(num==0)
{
flag=true;
ans=edge[i].len;
}
}
if(flag)
break;
}
if(flag)
printf("%d\n",ans);
else
printf("No Solution\n");
}
return 0;
}
二分加网络流(对网络流还是不理解,自己写的时候第一次二分,网络流跑完流量是对的,但是后面流量都为零了。。。不知道是哪里没有初始化,看了别人的代码,发现人家每次二分都要重新建下图,这是为什么呀?!!)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 40000
int n,m,ans,in,out;
int fa[500],f[500];
bool flag;
struct Edge{
int a,b,len;
}edge[MAXN];
int find(int x)
{
if(x!=fa[x])
fa[x]=find(fa[x]);
return fa[x];
}
bool cmp(Edge a,Edge b)
{
return a.len<b.len;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
int num=0;
memset(f,0,sizeof(f));
for(int i=0;i<n;i++)
{
scanf("%d",&in);
f[i+1]-=in;
}
for(int i=0;i<n;i++)
{
scanf("%d",&out);
f[i+1]+=out;
if(f[i+1]<0)num++;
}
scanf("%d",&m);
int a,b,c;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
edge[i].a=a;
edge[i].b=b;
edge[i].len=c;
}
sort(edge,edge+m,cmp);
int f1,f2;
for(int i=0;i<=n;i++)
fa[i]=i;
flag=false;
for(int i=0;i<m;i++)
{
f1=find(edge[i].a);
f2=find(edge[i].b);
if(f1!=f2)
{
fa[f1]=f2;
f[f2]+=f[f1];
if(f[f2]>=0)
{
if(f[f2]-f[f1]<0||f[f1]<0)
num--;
}
else if(f[f2]<0)
{
if(f[f2]-f[f1]<0&&f[f1]<0)
num--;
}
if(num==0)
{
flag=true;
ans=edge[i].len;
}
}
if(flag)
break;
}
if(flag)
printf("%d\n",ans);
else
printf("No Solution\n");
}
return 0;
}