luoguP2764

点击打开链接

网络流24题,题意是在有向无环图中求最小路径覆盖。

蒟蒻想不出。。看了题解才明白。。


建图思路:

首先,网络上是没有流的。每个节点自成一家。

然后。。考虑一个类似合并的操作:每有一条有向边,就可以考虑是否合并这两个节点,这个可以用网络流调整得出答案。

最后要输出的 答案,就是原来节点数n-合并的次数


具体实现:

对于序号为i的节点,拆成Xi与Yi两个部分

1、由s向所有Xi连一条流量为1的边

2、由所有Yi向t连一条流量为1的边

3、每有一条边(i,j)就从Xi向Yj连一条流量为1的边。若在网络流增广时使用了这条边,就说明两个节点合并。

答案很好统计。。


总结:

1、在做dinic的时候,又犯了一些错误,导致Wa了两次

2、还是不容易想到网络流的建图思路。。。

hhhhhhhhhhhhhhhhhhhhhhh

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstring>
#include<cctype>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<iomanip>
#include<sstream>
#include<cstdlib>
#include<ctime>
#include<list>
#include<deque>
#include<bitset>
#include<fstream>
#define ld double
#define ull unsigned long long
#define ll long long
#define pii pair<int,int >
#define iiii pair<int,pii >
#define mp make_pair
#define INF 1000000000
#define MOD 1000000007
#define rep(i,x) for(int (i)=0;(i)<(x);(i)++)
inline int getint()
{
	int x=0,p=1;char c=getchar();
	while (c<=32)c=getchar();
	if(c==45)p=-p,c=getchar();
	while (c>32)x=x*10+c-48,c=getchar();
	return x*p;
}
using namespace std;
//
const int maxn=500+5;
const int s=400;
const int t=401;
struct E
{
	int to,val,rev;
};
int n,m,res,dis[maxn],iter[maxn],ord[maxn],pre[maxn];
vector<E>G[maxn];
vector<int>ans[maxn];
queue<int>qu;
//
inline void faddedge(int x,int y)
{
	G[x].emplace_back((E){y,1,(int)G[y].size()});
	G[y].emplace_back((E){x,0,(int)G[x].size()-1});
}
bool bfs()
{
	memset(dis,-1,sizeof(dis));
	qu.push(s);dis[s]=0;
	while (!qu.empty())
	{
		int u=qu.front();
		qu.pop();
		rep(i,G[u].size())
		{
			E e=G[u][i];
			if(e.val>0&&dis[e.to]<0)
			{
				dis[e.to]=dis[u]+1;
				qu.push(e.to);
			}
		}
	}
	return (dis[t]>0);
}
int dfs(int v,int val)
{
	if(v==t)return val;
	while (iter[v]<G[v].size())
	{
		E &e=G[v][iter[v]];
		if(dis[e.to]>dis[v]&&e.val>0)
		{
			int ans=dfs(e.to,min(val,e.val));
			if(ans>0)
			{
				e.val-=ans;
				G[e.to][e.rev].val+=ans;
				return ans;
			}
		}
		iter[v]++;
	}
	return 0;
}
void dinic()
{
	while (bfs())
	{
		memset(iter,0,sizeof(iter));
		int f;
		while (f=dfs(s,INF));
	}
}
void sufsolve()
{
	memset(pre,-1,sizeof(pre));
	memset(ord,-1,sizeof(ord));
	rep(i,n)rep(j,G[i].size())
	{
		E e=G[i][j];
		if(e.val==0&&e.to>=n&&e.to<2*n)pre[e.to-n]=i;
	}
	int cnt=0;
	while (1)
	{
		rep(i,n)
		{
			if(pre[i]==-1)
			{
				ans[res++].emplace_back(i);
				ord[i]=res-1;
				cnt++;
			}
			else if(ord[pre[i]]>=0)
			{
				ans[ord[pre[i]]].emplace_back(i);
				ord[i]=ord[pre[i]];
				cnt++;
			}
		}
		if(cnt==n)break;
	}
	rep(i,res)
	{
		rep(j,ans[i].size())printf("%d ",ans[i][j]+1);
		putchar('\n');
	}
	printf("%d\n",res);
}
int main()
{
	n=getint();m=getint();
	rep(i,n)
	{
		faddedge(s,i);
		faddedge(i+n,t);
	}
	rep(i,m)
	{
		int x=getint()-1,y=getint()-1;
		faddedge(x,y+n);
	}
	dinic();
	sufsolve();
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值