我发现很多人关于输出方案那个地方解释都是错的,这不是误导别人吗!!!
能ac又怎样啊…
还有人说什么因为左边没满流,所以右边满流…
第一问,求最小代价
第二问
#include <iostream>
#include <queue>
using namespace std;
const int maxn=2e5+10;
const int inf=1e9;
int n,m,s,t,sumn,dis[maxn],a[maxn],b[maxn],id[maxn];
struct edge{
int to,nxt,flow;
}d[maxn]; int head[maxn],cnt=1;
void add(int u,int v,int flow){
d[++cnt]=(edge){v,head[u],flow},head[u]=cnt;
d[++cnt]=(edge){u,head[v],0},head[v]=cnt;
}
bool bfs()
{
for(int i=0;i<=t;i++) dis[i]=0;
dis[s]=1;
queue<int>q; q.push( s );
while( !q.empty() )
{
int u=q.front(); q.pop();
for(int i=head[u];i;i=d[i].nxt )
{
int v=d[i].to;
if( d[i].flow&&dis[v]==0 )
{
dis[v]=dis[u]+1;
if( v==t ) return true;
q.push( v );
}
}
}
return false;
}
int dinic(int u,int flow)
{
if( u==t ) return flow;
int res=flow;
for(int i=head[u];i&&res;i=d[i].nxt )
{
int v=d[i].to;
if( dis[v]==dis[u]+1&&d[i].flow)
{
int temp=dinic(v,min(res,d[i].flow) );
if( temp==0 ) dis[v]=0;
res-=temp;
d[i].flow-=temp;
d[i^1].flow+=temp;
}
}
return flow-res;
}
vector<int>vec;
int ok[maxn];
void dfs(int u)
{
for(int i=head[u];i;i=d[i].nxt )
{
int v=d[i].to;
if( ok[v]||d[i].flow==0 ) continue;
ok[v]=1; dfs(v);
}
}
int main()
{
cin >> n >> m;
s=0,t=n+n+1;
for(int i=1;i<=n;i++) cin >> a[i];
for(int i=1;i<=n;i++) cin >> b[i];
for(int i=1;i<=m;i++)
{
int l,r; cin >> l >> r;
add(l+n,r,inf);//l+n是出边,r是入边
}
for(int i=1;i<=n;i++)
{
add(s,i+n,b[i]);//出边被割掉,需要获得b[i]元
add(i,t,a[i] );//入边被割掉
}
int ans=0,shu=0;
while( bfs() ) ans+=dinic(s,inf);
cout << ans << '\n';
dfs(s); ok[s]=1;
for(int i=1;i<=n;i++)
{
if( ok[s]!=ok[i+n] ) shu++;
if( ok[t]!=ok[i] ) shu++;
}
cout << shu << '\n';
for(int i=1;i<=n;i++)
{
if( ok[s]!=ok[i+n] ) cout << i << " -\n";
if( ok[t]!=ok[i] ) cout << i << " +\n";
}
}