accounts_somebody @ 2023-05-05 19:01:20
rt,用的Dinic,写了调试代码,发现是bfs一直等于true
求助!
#include<bits/stdc++.h>
using namespace std;
const int N=205,mx=0x3f3f3f3f;
int n,m,s,t,ans,dis[N];
struct Node
{
int to,w;
};
vector<Node>nbr[N];
bool bfs()
{
queue<int>q;
memset(dis,0x3f,sizeof dis);
int cur=s;
q.push(cur);
dis[s]=0;
while(!q.empty())
{
cur=q.front();
q.pop();
for(int i=0;i<nbr[cur].size();i++)
{
int nxt=nbr[cur][i].to,w=nbr[cur][i].w;
if(dis[nxt]==mx&&w>0)
{
q.push(nxt);
dis[nxt]=dis[cur]+1;
if(nxt==t)
return true;
}
}
}
return false;
}
int dfs(int x,int sum)
{
if(x==t)
return sum;
int num=0;
for(int i=0;i<nbr[x].size();i++)
{
int nxt=nbr[x][i].to,w=nbr[x][i].w;
if(dis[x]+1==dis[nxt]&&w>0)
{
int val=dfs(nxt,min(sum,w));
nbr[x][nxt].w-=val;
nbr[nxt][x].w+=val;
num+=val;
sum-=val;
}
}
return num;
}
int main()
{
cin>>n>>m>>s>>t;
for(int i=1;i<=m;i++)
{
int x,y,w;
cin>>x>>y>>w;
nbr[x].push_back((Node){y,w});
nbr[y].push_back((Node){x,0});
}
while(bfs()==true)
{
ans+=dfs(s,mx);
}
cout<<ans;
return 0;
}
by 2019zll @ 2023-05-05 19:20:19
反向边不是这样判断的啊,dfs 函数里面错了。
我的建议是使用链式前向星存图,边的编号从
by 2019zll @ 2023-05-05 19:22:00
当然了,对于这道题,开一个
by 2019zll @ 2023-05-05 19:23:09
为了以后的方便(比如
@li_bai_Delete
by accounts_somebody @ 2023-05-05 19:41:26
@2019zll 您指出了dfs的错误,但我希望您指出是哪一行,哪一个步骤来具体说明,另外,本人并没有学链式前向星,所以习惯用vector来存图。
by 2019zll @ 2023-05-05 19:55:36
nbr[x][nxt].w-=val;
nbr[nxt][x].w+=val;
这里你错以为是普通二维数组存图了。
@li_bai_Delete
by 2019zll @ 2023-05-05 19:57:37
提供我的代码
#include<cstdio>
#include<cstring>
template<typename T>
void read(T&num){
int ch=getchar();
num=0;
while(ch<48||ch>57)ch=getchar();
while(ch>=48&&ch<=57)num=(num<<3)+(num<<1)+(ch^48),ch=getchar();
}
template<typename T>
void write(T a){
static int ch[20],cnt=0;
if(a==0)putchar('0');
while(a)ch[cnt++]=a%10|48,a/=10;
while(cnt)putchar(ch[--cnt]);
}
template<typename T>
inline T min(const T a,const T b){
return a<b?a:b;
}
typedef long long ll;
const int maxn=10000,maxm=100000;
const ll inf=0x7fffffffffffffff;
int n,m,s,t;
int head[maxn+1],cur[maxn+1],total=1;//total 从 1 而不是 0 开始。
struct Edge{
int to,next,flow;
}e[maxm*2+2];
void add(const int u,const int v,const int w){
e[++total]=Edge{v,head[u],w};//++total
head[u]=total;
}
int dep[maxn+1];
int q[maxn+1],front,tail;
bool bfs(){
memset(dep+1,-1,sizeof(int)*n);
front=1,tail=0;
q[++tail]=s;
dep[s]=0;
while(front<=tail){
const int u=q[front++];
for(int i=head[u];i;i=e[i].next){
const int v=e[i].to;
if(e[i].flow&&dep[v]==-1){
dep[v]=dep[u]+1;
q[++tail]=v;
}
}
}
return dep[t]!=-1;
}
ll dfs(const int u,ll in){
if(u==t)return in;
ll out=0;
for(int&i=cur[u];i;i=e[i].next){
const int v=e[i].to;
if(e[i].flow&&dep[v]==dep[u]+1){
const int res=dfs(v,min(in,(ll)e[i].flow));
in-=res;
out+=res;
e[i].flow-=res;
e[i^1].flow+=res;//反向边就是通过异或 1 实现的。
if(!in)break;
}
}
if(!out)dep[u]=-1;
return out;
}
ll maxflow;
void dinic(){
while(bfs()){
memcpy(cur+1,head+1,sizeof(int)*n);
maxflow+=dfs(s,inf);
}
}
int main(){
read(n),read(m),read(s),read(t);
for(int i=1,u,v,w;i<=m;i++){
read(u),read(v),read(w);
add(u,v,w),add(v,u,0);
}
dinic();
write(maxflow),putchar('\n');
return 0;
}
by 2019zll @ 2023-05-05 19:59:30
如果你非要用 vector 存图,就需要对每条边存个编号,更麻烦,不如链式前向星边自带编号,建议你学一下,日子久了自然会背熟的。
by accounts_somebody @ 2023-05-05 20:39:37
@2019zll 谢谢,刚刚自学了链式前向星,我改完之后,发现还是卡死了,请您再帮忙看一看。
#include<bits/stdc++.h>
using namespace std;
const int N=205,mx=0x3f3f3f3f;
int n,m,s,t,ans,dis[N],head[N],cnt=1;
struct eg
{
int next,to,w;
}e[N];
struct Node
{
int to,w;
};
vector<Node>nbr[N];
void add(int v,int u,int w)
{
e[++cnt].w=w;
e[cnt].to=u;
e[cnt].next=head[v];
head[v]=cnt;
return ;
}
bool bfs()
{
queue<int>q;
memset(dis,-1,sizeof dis);
int cur=s;
q.push(cur);
dis[s]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=e[i].next)
{
int v=nbr[cur][i].to,w=nbr[cur][i].w;
if(dis[v]==mx&&w>0)
{
q.push(v);
dis[v]=dis[u]+1;
if(v==t)
return true;
}
}
}
return false;
}
int dfs(int u,int sum)
{
if(u==t)
return sum;
int num=0;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to,w=e[i].w;
if(dis[u]+1==dis[v]&&w>0)
{
int val=dfs(v,min(sum,w));
e[i].w-=val;
e[i^1].w+=val;
num+=val;
sum-=val;
}
}
return num;
}
int main()
{
cin>>n>>m>>s>>t;
for(int i=1;i<=m;i++)
{
int x,y,w;
cin>>x>>y>>w;
add(x,y,w);
add(y,x,0);
}
while(bfs()==true)
{
ans+=dfs(s,mx);
}
cout<<ans;
return 0;
}
by 2019zll @ 2023-05-05 20:41:09
好的我看看
by 2019zll @ 2023-05-05 20:42:48
int v=nbr[cur][i].to,w=nbr[cur][i].w;
这里把 cur 改成 u!