0
点赞
收藏
分享

微信扫一扫

POJ 3921 - DFSID


     同样是<ACM国际大学生程序设计竞赛亚洲区域真题题解>上的一题...本题的解法听说有网络流...构了一下没构出来..而且听说构图跑最大流的解法并不完备...存在Bug...所以还是搜了...DFSID神马的还是超级给力啊...907MS压线水过...

     开始的时候各种超时...一个很重要的原因就是提供的点为50..但边有4000条...显然所需的信息里两个点有一条边和两个点有 N条边是一回事...将冗余的边通通剔除...所以我干脆就用个邻接表来整了...还有就是搜索当前条件下从1~n的最短时间..也没必要用dijkstra和SPFA..反而效率低..因为每条边长相等...直接BFS就行了...

      枚举当前删点个数 ...判断在删除小于等于这么多点的条件下能否使1~n的最短时间大于k...所以每次找出最短路..枚举删去这条路上的一个点.. 再继续找最短路..知道删点个数到达所卡的个数...或者1~n找不到路径了...再判断....


Program:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
#include<queue>
#include<stack>
#define ll long long
#define oo 1000000000
#define pi acos(-1)
using namespace std;
int n,m,k,pre[55];
bool note[55],arc[55][55];
queue<int> myqueue;
bool BFS()
{
int h,i,dis[55];
memset(dis,0x7f,sizeof(dis));
while (!myqueue.empty()) myqueue.pop();
myqueue.push(1);
dis[1]=0;
while (!myqueue.empty())
{
h=myqueue.front();
myqueue.pop();
if (h==n) break;
for (i=1;i<=n;i++)
if (arc[h][i] && !note[i] && dis[i]>oo)
{
dis[i]=dis[h]+1;
pre[i]=h;
myqueue.push(i);
}
}
if (dis[n]>k) return true;
return false;
}
bool FindAns(int p)
{
int way[55],i,m;
if (BFS()) return true;
if (!p) return false;
i=pre[n];
m=0;
while (i!=1)
{
way[++m]=i;
i=pre[i];
}
for (i=m;i>=1;i--)
{
note[way[i]]=true;
if (FindAns(p-1)) return true;
note[way[i]]=false;
}
return false;
}
int main()
{
int p,x,y,ans;
while (~scanf("%d%d%d",&n,&m,&k))
{
if (!n && !m && !k) break;
memset(arc,false,sizeof(arc));
while (m--)
{
scanf("%d%d",&x,&y);
arc[x][y]=true;
}
for (ans=0;ans<n;ans++)
{
memset(note,false,sizeof(note));
if (FindAns(ans)) break;
}
printf("%d\n",ans); //r
}
return 0;
}



举报

相关推荐

0 条评论