POJ2594 Treasure Exploration
Posted yspm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2594 Treasure Exploration相关的知识,希望对你有一定的参考价值。
Description
我的题面和 (POJ) 上的不太一样
有一些伞兵和一个 (DAG),可以给伞兵任意指定下降的节点,让它遍历整个图
每个伞兵的路径可以重复
(n le 100) (随便做)
Solution
首先一个前置题目:UVA1184 Air Raid
这个题是个裸的有向无环图的最小路径覆盖问题
首先要发现这个题的两个相交的路径:(x ightarrow y ightarrow z) 和路径 (u ightarrow y ightarrow v)
这里如果我们添加一条边((x,z))
那么问题又转化成了最小点覆盖((x ightarrow z) 和 (u ightarrow y ightarrow v) )
这里搞一个 (Floyd) 传递闭包搞连通性然后最大匹配就好了
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
#define int long long
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k==‘-‘) f=-1;
while(isdigit(k)) res=res*10+k-‘0‘,k=getchar();
return res*f;
}
const int N=1010;
struct node{
int nxt,to;
}e[N<<9];
int head[N],cnt;
inline void add(int u,int v)
{
e[++cnt].nxt=head[u]; e[cnt].to=v;
return head[u]=cnt,void();
}
int to[N],vis[N],n,m;
inline bool dfs(int x)
{
for(int i=head[x];i;i=e[i].nxt)
{
int t=e[i].to; if(vis[t]) continue;
vis[t]=1; if(!to[t]||dfs(to[t])) return to[t]=x,1;
}
return 0;
}
inline int max_match()
{
int ans=0;
for(int i=1;i<=n;++i)
{
memset(vis,0,sizeof(vis));
ans+=dfs(i);
}
return ans;
}
int f[N][N];
inline void prework()
{
memset(f,0,sizeof(f)); memset(head,0,sizeof(head));
memset(to,0,sizeof(to)); memset(e,0,sizeof(e));
cnt=0;
return ;
}
inline void work()
{
m=read();
for(int i=1;i<=m;++i)
{
int u=read(),v=read();
f[u][v]=1;
}
for(int k=1;k<=n;++k)
{
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
{
f[i][j]|=f[i][k]&&f[k][j];
}
}
}
for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) if(f[i][j]) add(i,j);
cout<<n-max_match()<<endl;
return prework();
}
signed main()
{
while(n=read()) work();
return 0;
}
}
signed main(){return yspm::main();}
以上是关于POJ2594 Treasure Exploration的主要内容,如果未能解决你的问题,请参考以下文章
POJ2594:Treasure Exploration(Floyd + 最小路径覆盖)
POJ2594 Treasure Exploratio —— 最小路径覆盖 + 传递闭包
POJ2594Treasure Exploration(最小路径覆盖,相交)