王晓东《线性规划和网络流24题》
求最小点路径覆盖并打印
#include
#include
using namespace std;
const int maxn=450;
const int inf=1<<25;
const int s=0;
int n,m;
struct edge{
int v,next,w;
}edge[maxn*maxn];
int head[maxn],cnt;//for sap
void addedge(int u, int v, int w)
{
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].v=u;
edge[cnt].w=0;
edge[cnt].next=head[v];
head[v]=cnt++;
}
int sap(int t)
{
int pre[maxn],cur[maxn];
int dis[maxn],gap[maxn];
int flow=0 , aug=inf ,u;
bool flag;
for (int i=0 ; i<=t ; ++i)
{
cur[i]=head[i];
gap[i]=dis[i]=0;
}
gap[s]=t+1;
u=pre[s]=s;
while (dis[s]<=t)
{
flag=0 ;
for (int &j=cur[u] ; ~j ; j=edge[j].next)
{
int v=edge[j].v;
if (edge[j].w>0 && dis[u]==dis[v]+1)
{
flag=1;
if(edge[j].w0 && dis[v]
JOJ 2730 stock(torry唐牛出品)
给出n个k长的序列,问最少需要多少个图画出所有的序列,使每个图的序列不相交。
一开构图时根据2点之间不相交的关系连无向边,结果构出了一个有环无向图(囧)。
正确构图方法是将无向定义有向,并去环, 这样可以考虑使等价关系变成偏序关系,即互不相交变成当一个序列完全大于另一个序列时连一条有向边,这样就是标准的DAG图,再求下最小路径覆盖就好了。
#include
#include
const int maxn=210;
const int inf=1<<25;
const int s=0;
int n,m;
struct edge{
int v,next,w;
}edge[maxn*maxn];
int head[maxn],cnt;//for sap
void addedge(int u, int v, int w)
{
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].v=u;
edge[cnt].w=0;
edge[cnt].next=head[v];
head[v]=cnt++;
}
int sap(int t)
{
int pre[maxn],cur[maxn];
int dis[maxn],gap[maxn];
int flow=0 , aug=inf ,u;
bool flag;
for (int i=0 ; i<=t ; ++i)
{
cur[i]=head[i];
gap[i]=dis[i]=0;
}
gap[s]=t+1;
u=pre[s]=s;
while (dis[s]<=t)
{
flag=0 ;
for (int &j=cur[u] ; ~j ; j=edge[j].next)
{
int v=edge[j].v;
if (edge[j].w>0 && dis[u]==dis[v]+1)
{
flag=1;
if(edge[j].w0 && dis[v]