HDU 2485 Destroying the bus stations (IDA*+ BFS)

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2485


题意:给你n个点,m条相连的边,问你最少去掉几个点使从1到n最小路径>=k,其中不能去掉1,n两个点。

题解:这个题目可以用最小流解决,也可以用IDA*  +  BFS解决。


AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;

#define si1(a) scanf("%d",&a)
#define si2(a,b) scanf("%d%d",&a,&b)
#define sd1(a) scanf("%lf",&a)
#define sd2(a,b) scanf("%lf%lf",&a,&b)
#define ss1(s)  scanf("%s",s)
#define pi1(a)    printf("%d\n",a)
#define pi2(a,b)  printf("%d %d\n",a,b)
#define mset(a,b)   memset(a,b,sizeof(a))
#define forb(i,a,b)   for(int i=a;i<b;i++)
#define ford(i,a,b)   for(int i=a;i<=b;i++)

typedef long long LL;
const int N=1005;
const int M=105;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-7;

int n,m,k;
int lin[N][N];//邻接表储存
int fa[N];//记录从1到n最短路径
bool vis[N];//标记节点是否被删除
int ans,Min;
bool flag;

struct xh
{
    int x,y,next;
}edge[N];

int bfs()
{
    int q[2222];
    int he=0,ta=0;
    mset(fa,-1);
    fa[1]=0;
    mset(q,0);
    q[ta++]=1;
    while(he!=ta)
    {
        int x=q[he++];
        for(int i=1;i<=lin[x][0];i++)
        {
            int v=lin[x][i];
            if(fa[v]==-1&&!vis[v])
            {
                fa[v]=x;
                q[ta++]=v;
                if(n==v)    return 1;
            }
        }
    }
    return 0;
}

void dfs(int dian,int depth)//求去掉最少个数点
{
    if(flag==false) return ;
    if(dian>depth) return ;

    int p=bfs();
    int sa[N]={0},t=0;
    if(p==0){flag=false;return;}
    for(int i=n;i!=1;i=fa[i])
    {
        sa[t++]=i;
        if(t>k){flag=false;return ;}
    }

    for(int i=1;i<t;i++)
    {
        int x=sa[i];
        if(vis[x])  continue;
        vis[x]=1;
        dfs(dian+1,depth);
        vis[x]=0;
        if(flag==false) return ;
    }
}

void IDA()
{
    if(n<=2)
    {
        puts("0");
        return ;
    }
    int depth=0;
    flag=true;
    vis[1]=1;
    while(flag)
    {
        dfs(0,depth);
        if(!flag)   break;
        depth++;
    }
    pi1(depth);
}

int main()
{
//    freopen("input.txt","r",stdin);
    while(scanf("%d%d%d",&n,&m,&k)&&(n+m+k))
    {
        mset(lin,0);
        forb(i,0,m)
        {
            int a,b,t;
            si2(a,b);
            t=++lin[a][0];
            lin[a][t]=b;
            //这个地方写双向的就WA了,单向的就A了
        }
        IDA();
    }
    return 0;
}




超时代码:(IDA*  +  DFS)个人感觉应该差不多,但是就是超时了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;

#define si1(a) scanf("%d",&a)
#define si2(a,b) scanf("%d%d",&a,&b)
#define sd1(a) scanf("%lf",&a)
#define sd2(a,b) scanf("%lf%lf",&a,&b)
#define ss1(s)  scanf("%s",s)
#define pi1(a)    printf("%d\n",a)
#define pi2(a,b)  printf("%d %d\n",a,b)
#define mset(a,b)   memset(a,b,sizeof(a))
#define forb(i,a,b)   for(int i=a;i<b;i++)
#define ford(i,a,b)   for(int i=a;i<=b;i++)

typedef long long LL;
const int N=1005;
const int M=105;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-7;

int n,m,k;
int lin[N][N];//邻接表储存
int cnt[M];//记录从1到n最短路径
bool vis[N];//标记节点是否被删除
int ans,Min;
bool flag;

struct xh
{
    int x,y,next;
}edge[N];

void dfs2(int k,int de)//求最短距离
{
    cnt[de]=k;//路径
    if(k==n)
    {
        Min=min(Min,de);
        return ;
    }

    for(int i=1;i<=lin[k][0];i++)
    {
        int t=lin[k][i];
        if(vis[t])  continue;
        vis[t]=1;
        dfs2(t,de+1);
        vis[t]=0;
    }
}

void dfs1(int dian,int depth)//求去掉最少个数点
{
    if(flag==false) return ;
    Min=INF;
    mset(cnt,0);
    dfs2(1,0);
//    cout<<"最短距离"<<Min<<endl;
//    cout<<"路径:";
//    if(Min!=INF)
//    {
//        for(int i=0;i<=Min;i++)
//            printf("%d ",cnt[i]);
//        cout<<endl;
//    }
//    system("pause");

    int xh=Min;
    if(xh>=k)
    {
        flag=false;
        ans=min(ans,dian);
        return ;
    }
    if(dian>=depth)
        return ;

    int sa[N];
    for(int i=0;i<=xh;i++)
        sa[i]=cnt[i];
    for(int i=1;i<xh;i++)
    {
        int t=sa[i];
        if(vis[t])  continue;
        vis[t]=1;
        dfs1(dian+1,depth);
        vis[t]=0;
        if(flag==false) return ;
    }
}

int main()
{
//    freopen("input.txt","r",stdin);
    while(scanf("%d%d%d",&n,&m,&k)&&(n+m+k))
    {
        mset(lin,0);
        forb(i,0,m)
        {
            int a,b,t;
            si2(a,b);
            t=++lin[a][0];
            lin[a][t]=b;
            t=++lin[b][0];
            lin[b][t]=a;
        }
        ans=INF;
        mset(vis,0);
        vis[1]=1;
        flag=true;
        int depth=-1;
        while(flag)
        {
            depth++;
            dfs1(0,depth);
        }

        pi1(depth);
    }
    return 0;
}


你可能感兴趣的:(HDU 2485 Destroying the bus stations (IDA*+ BFS))