• 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
    ",a)
    #define pi2(a,b)  printf("%d %d
    ",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
    ",a)
    #define pi2(a,b)  printf("%d %d
    ",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;
    }
    


  • 相关阅读:
    设计模式:迭代器模式
    设计模式:观察者模式
    设计模式:解释器模式
    设计模式:策略模式
    设计模式:状态模式
    设计模式:代理模式
    strtok函数
    人们眼中的程序员
    如何用C语言获取文件的大小
    C++著名库的比较和学习经验
  • 原文地址:https://www.cnblogs.com/pangblog/p/3348085.html
Copyright © 2020-2023  润新知