POJ3713: Transferring Sylla 题解

来源:互联网 发布:湖南软件职业学院新闻 编辑:程序博客网 时间:2024/06/05 03:18

如果任意两个顶点之间都有至少三条没有重复顶点的路径,那么这个图中任意删除两个顶点,一定还是连通的。这是充要条件,非常重要

朴素想法是枚举删除哪两个点,再跑一遍dfs。但这样是O(n*n*m)的,会超时

可以枚举删除那个点,再用tarjan判断有没有割点这样就是O(n*m)的,可以通过

有考虑过网络流的方法

因为任意点都不能重复走两次,然后就考虑拆点,拆成in和out,然后之间连一条流量为1的边

按照题目要求连好边,然后枚举起点终点判断最大流是否>=3

但是这样会TLE。。。

#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cmath>#include <algorithm>#include <cstdlib>#include <utility>#include <map>#include <stack>#include <set>#include <vector>#include <queue>#include <deque>#define x first#define y second#define mp make_pair#define pb push_back#define LL long long#define Pair pair<int,int>#define LOWBIT(x) x & (-x)using namespace std;const int MOD=1e9+7;const int INF=1e9;const int magic=348;int taboo;int tot=1,head[1048],nxt[100048],to[100048];inline void addedge(int s,int t){to[++tot]=t;nxt[tot]=head[s];head[s]=tot;to[++tot]=s;nxt[tot]=head[t];head[t]=tot;}int par[1048];int n,e;int dfn[1048],time=0,low[1048];bool visited[1048];bool dfs(int x){int i,y;visited[x]=true;dfn[x]=low[x]=++time;int cnt=0;for (i=head[x];i;i=nxt[i]){y=to[i];if (y==taboo) continue;if (!visited[y]){par[y]=x;if (dfs(y)) return true;cnt++;low[x]=min(low[x],low[y]);if (par[x]==-1 && cnt>1) return true;if (par[x]!=-1 && low[y]>=dfn[x]) return true;}elseif (y!=par[x]) low[x]=min(low[x],dfn[y]);}return false;}int main (){int i,j,x,y;while (scanf("%d%d",&n,&e) && n){tot=1;for (i=1;i<=n;i++) head[i]=0;for (i=1;i<=e;i++){scanf("%d%d",&x,&y);x++;y++;addedge(x,y);}taboo=-1;time=0;for (i=1;i<=n;i++){visited[i]=false;par[i]=-1;}if (dfs(1)){printf("NO\n");continue;}for (i=1;i<=n;i++)if (!visited[i]){printf("NO\n");break;}if (i<=n) continue;for (i=1;i<=n;i++){taboo=i;for (j=1;j<=n;j++){visited[j]=false;par[j]=-1;}int start=(i==1)?2:1;time=0;if (dfs(start)){printf("NO\n");break;}}if (i<=n) continue;printf("YES\n");}return 0;}



原创粉丝点击