zoj 3583 Simple Path
来源:互联网 发布:广州ps美工培训 编辑:程序博客网 时间:2024/06/05 06:07
题意:给定一个无向图,输出不在s到d的简单路径上的点
题解:
1方法1dfs
先删点,然后从(前提:删除的不是s且s没有被拜访)s搜一次,再从(前提:删除的不是d且d没有被拜访)d搜一次,搜不到的点就是不再s到d简单路径上的点。
一开始错在这个图上了:
从0到4
0 1
0 2
0 3
0 4
#include<iostream>#include<cstdio>#include<cstring>using namespace std;bool v[111],not_in[111],a[111][111];int n,m,s,d;void dfs(int x){ for(int i=0;i<=n-1;i++) if((!v[i])&&a[x][i]) { v[i]=true; dfs(i); }}int main(){ while(scanf("%d%d%d%d",&n,&m,&s,&d)!=EOF) { memset(a,false,sizeof(a)); memset(not_in,false,sizeof(not_in)); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); a[u][v]=true; a[v][u]=true; } for(int i=0;i<=n-1;i++) { memset(v,false,sizeof(v)); v[i]=true; if(!v[s])dfs(s);//必须加上!v if(!v[d])dfs(d);//必须加上!v /* 0 1 0 2 0 3 0 4 看这种图,必须删除点s后才能发现不在简单路径上的点。 */ for(int j=0;j<=n-1;j++) if(!v[j]&&j!=s&&j!=d)not_in[j]=true; } int ans=0; for(int i=0;i<=n-1;i++) if(not_in[i])ans++; printf("%d\n",ans); } return 0;}
2.建立网络流模型求解
注意本题有重边,必须处理重边否则会出现错误。
建立图的依据:u如果不在简单路径上,则有s->u的路径与d->u的路径必然会经过同一个点。
方法:
建立超级汇点ss,超级源点dd,ss到s连流量为1的边,dd到d连流量为1的边。原图中的边流量设为无穷。对于每个点拆点,之间流量为1.但是对于u这个点,流量为2。
u和超级汇点也连边。
求超级源点到超级汇点的流量。
#include<iostream>#include<cstdio>#include<cstring>#define INF (1<<26)using namespace std;template <int MAXSIZE,int MAXQ>class DINIC//建立对象时先调用清除函数{ public: void clear(int n0) { m=0;n=n0; memset(edge,-1,sizeof(edge)); memset(next,-1,sizeof(next)); } void addedge(int u,int v,int c) { to[m]=v; cap[m]=c; next[m]=edge[u]; edge[u]=m++; to[m]=u; cap[m]=0; next[m]=edge[v]; edge[v]=m++; } bool bfs() { for(int i=0;i<=n;i++) d[i]=-1; int head=0,tail=0,x,y; d[s]=0;q[0]=s; while(head<=tail) { x=q[head];head=(head+1)%MAXQ;int i=edge[x]; while(i!=-1) { y=to[i]; if(cap[i] && d[y]==-1) { d[y]=d[x]+1; if(y==t)return true; tail=(tail+1)%MAXQ;q[tail]=y; } i=next[i]; } } return false; } int find(int x,int low=INF) { if(x==t)return low; int ret,y,ans=0,i=edge[x]; while(i!=-1 && low>0) { y=to[i]; if(cap[i]>0 && d[y]==d[x]+1 && (ret=find(y,min(low,cap[i])))) { cap[i]-=ret; cap[i^1]+=ret; low-=ret; ans+=ret; } i=next[i]; } return ans; } int dinic(int s0,int t0) { s=s0;t=t0; int ans=0; while(bfs()) ans+=find(s); return ans; } private: int m,s,t,n; int to[MAXSIZE],cap[MAXSIZE],next[MAXSIZE],edge[MAXSIZE],d[MAXSIZE],q[MAXQ];};DINIC<60010,600000> a;bool g[201][201];int main(){ int n,m,s,d,supers,supert; while(scanf("%d%d%d%d",&n,&m,&s,&d)!=EOF) { memset(g,false,sizeof(g)); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); g[u][v]=true; g[v][u]=true; } //s,t int ans=0; for(int i=0;i<=n-1;i++) if(i!=s && i!=d) { a.clear(2*n+1); supers=2*n;supert=2*n+1; a.addedge(supers,s,1); a.addedge(supers,d,1); a.addedge(i+n,supert,2); for(int x=0;x<=n-1;x++) for(int y=0;y<=n-1;y++) if(g[x][y]) a.addedge(x+n,y,INF); for(int j=0;j<=n-1;j++) if(j!=i) a.addedge(j,j+n,1); else a.addedge(j,j+n,2); int sum=a.dinic(supers,supert); if(sum<=1) ans++; } printf("%d\n",ans); } return 0;}
- zoj 3583 Simple Path
- zoj 3583 simple path
- zoj 3583 Simple Path
- zoj3583 Simple Path
- hdu 4338 Simple Path
- hdu4338 Simple Path
- ZOJ 3753 Simple Equation
- ZOJ 3753 Simple Equation
- ZOJ Very Simple Counting
- ZOJ 3293 Simple Sequence
- zoj-3658-Simple Function
- ZOJ 3286 Very Simple Counting
- zoj 1241 Geometry Made Simple
- zoj 1382 A Simple Task
- ZOJ 1241 Geometry Made Simple
- ZOJ 1382 A Simple Task
- zoj 1241.Geometry Made Simple
- zoj 1241 Geometry Made Simple
- (*(volatile unsigned long *)
- IPv6
- flash脚本AS3.0载入网络对象
- 10只狗怎么鉴别1000瓶水哪瓶有毒
- android之MultiAutoCompleteTextView
- zoj 3583 Simple Path
- 转载 程序员之路
- 短暂的时光,漫长的征程(菜鸟成长史)——年度总结
- Linux常用命令大全
- 二叉树后序遍历(非递归)
- Ubuntu12.10安装pptpd提供vpn服务
- Linux shell 进制转换
- AForge.Net
- Java 连接池的工作原理