zoukankan      html  css  js  c++  java
  • pat 1087 (dfs)

    原题:

     

    代码(dfs):

    #include<iostream>
    #include<vector>
    #include<unordered_map>
    #include<limits.h>
    using namespace std;
    
    int mindis[201];
    vector <int> path;
    int num_way;//number of the same ways
    int destination;
    string namelist[200];
    int happy[200];
    int dis[200][200];
    vector<int> final_path;
    int final_dis,final_happy,final_step;
    vector<int> v[200];// its neghbor
    unordered_map<string,int>city_num;
    
    void dfs (int curcity,int curdis,int curhappy,int curstep)
    {
        if( curdis> mindis[curdis]) return;//stop loss
        path.emplace_back(curcity);
        if(curcity == destination)//如果到了终点
        {
            if(curdis < mindis[destination])
            {
                mindis[destination] = curdis;
                final_path = path;
                final_dis = curdis;
                final_happy = curhappy;
                final_step = curstep;
                num_way = 1;
            }
            if(curdis == mindis[destination])   //equal case
            {
                num_way++;
                if(curhappy> final_happy || (curhappy == final_happy && curstep < final_step))
                {
                    final_path = path;
                    final_dis = curdis;
                    final_happy = curhappy;
                    final_step = curstep;
                }
            }
        }
        else // not reach the destination
        {
            if( curdis <  mindis[curdis])
                   mindis[curcity] = curdis;
            for(int each:v[curcity])//find the neighbor
            {
                dfs(each,curdis+dis[curcity][each],curhappy+happy[each],curstep+1);
            }
        }
        path.pop_back();    
    }
    
    
    int main()
    {
        int N,K; //N是城市数,K是路的数量   
        string s_city;
        cin>>N>>K>>s_city;    city_num[s_city] = 0; namelist[0] = s_city;
        for(int i =1;i<=N-1;i++) mindis[i] = INT_MAX;
        //接下来的N-1行: 城市名 幸福值
        string city;happy[0] = 0;
        for(int i = 1;i<=N-1;i++ )
        {
            cin>>city>>happy[i];
            city_num[city] = i; //将城市转化为数字序号便于dfs
            namelist[i] = city; 
        }
        
        //接下来存城市之间的距离,用城市序号表示
        string s1,s2;int d;
        int c1,c2;
        while(K--)
        {
            cin>>s1>>s2>>d;
            dis[city_num[s1]][city_num[s2]] = d;
            dis[city_num[s2]][city_num[s1]] = d;
            
            c1 = city_num[s1];c2= city_num[s2];
            v[c1].emplace_back(c2);
            v[c2].emplace_back(c1);
        }
        destination =city_num["ROM"];
        dfs(0,0,0,0);
        cout<<num_way<<" "<<final_dis<<" "<<final_happy<<" "<<final_happy/final_step<<endl;
        cout<<s_city;
        for(unsigned int i = 1;i<final_path.size();i++)
            cout<<"->"<<namelist[final_path[i]];
        return 0;
        
    }

    结果只是部分正确:

     如果改一下,

     if(curdis == mindis[destination])   //equal case
    其实可以改成else

    代码:

    #include<iostream>
    #include<vector>
    #include<unordered_map>
    #include<limits.h>
    using namespace std;
    
    int mindis[201];
    vector <int> path;
    int num_way;//number of the same ways
    int destination;
    string namelist[200];
    int happy[200];
    int dis[200][200];
    vector<int> final_path;
    int final_dis,final_happy,final_step;
    vector<int> v[200];// its neghbor
    unordered_map<string,int>city_num;
    
    void dfs (int curcity,int curdis,int curhappy,int curstep)
    {
        if( curdis> mindis[curdis]) return;//stop loss
        path.emplace_back(curcity);
        if(curcity == destination)//如果到了终点
        {
            if(curdis < mindis[destination])
            {
                mindis[destination] = curdis;
                final_path = path;
                final_dis = curdis;
                final_happy = curhappy;
                final_step = curstep;
                num_way = 1;
            }
            else  //equal case
            {
                num_way++;
                if(curhappy> final_happy || (curhappy == final_happy && curstep < final_step))
                {
                    final_path = path;
                    final_dis = curdis;
                    final_happy = curhappy;
                    final_step = curstep;
                }
            }
        }
        else // not reach the destination
        {
            if( curdis <  mindis[curdis])
                   mindis[curcity] = curdis;
            for(int each:v[curcity])//find the neighbor
            {
                dfs(each,curdis+dis[curcity][each],curhappy+happy[each],curstep+1);
            }
        }
        path.pop_back();    
    }
    
    
    int main()
    {
        int N,K; //N是城市数,K是路的数量   
        string s_city;
        cin>>N>>K>>s_city;    city_num[s_city] = 0; namelist[0] = s_city;
        for(int i =1;i<=N-1;i++) mindis[i] = INT_MAX;
        //接下来的N-1行: 城市名 幸福值
        string city;happy[0] = 0;
        for(int i = 1;i<=N-1;i++ )
        {
            cin>>city>>happy[i];
            city_num[city] = i; //将城市转化为数字序号便于dfs
            namelist[i] = city; 
        }
        
        //接下来存城市之间的距离,用城市序号表示
        string s1,s2;int d;
        int c1,c2;
        while(K--)
        {
            cin>>s1>>s2>>d;
            dis[city_num[s1]][city_num[s2]] = d;
            dis[city_num[s2]][city_num[s1]] = d;
            
            c1 = city_num[s1];c2= city_num[s2];
            v[c1].emplace_back(c2);
            v[c2].emplace_back(c1);
        }
        destination =city_num["ROM"];
        dfs(0,0,0,0);
        cout<<num_way<<" "<<final_dis<<" "<<final_happy<<" "<<final_happy/final_step<<endl;
        cout<<s_city;
        for(unsigned int i = 1;i<final_path.size();i++)
            cout<<"->"<<namelist[final_path[i]];
        return 0;
        
    }

    最终竟然全错、。。。

    感觉应该是很简单的一个dfs,不知道为什么这个num_way 总是错误

    找了一晚上,后来很生气地发现:

     有个地方 curdis和curcity太像了,变量名起的像,都有current 想表示现在的距离和城市

    我给搞混了

     之后代码是:

    #include<iostream>
    #include<vector>
    #include<unordered_map>
    #include<limits.h>
    using namespace std;
    
    int mindis[201];
    vector <int> path;
    int num_way;//number of the same ways
    int destination;
    string namelist[200];
    int happy[200];
    int dis[200][200];
    vector<int> final_path;
    int final_dis,final_happy,final_step;
    vector<int> v[200];// its neghbor
    unordered_map<string,int>city_num;
    
    void dfs (int curcity,int curdis,int curhappy,int curstep)
    {
        if( curdis> mindis[curcity]) return;//stop loss
        path.emplace_back(curcity);
        if(curcity == destination)//如果到了终点
        {
            if(curdis < mindis[destination])
            {
                mindis[destination] = curdis;
                final_path = path;
                final_dis = curdis;
                final_happy = curhappy;
                final_step = curstep;
                num_way = 1;
            }
            else  //equal case
            {
                num_way++;
                if(curhappy> final_happy || (curhappy == final_happy && curstep < final_step))
                {
                    final_path = path;
                    final_dis = curdis;
                    final_happy = curhappy;
                    final_step = curstep;
                }
            }
        }
        else // not reach the destination
        {
            if( curdis <  mindis[curdis])
                   mindis[curcity] = curdis;
            for(int each:v[curcity])//find the neighbor
            {
                dfs(each,curdis+dis[curcity][each],curhappy+happy[each],curstep+1);
            }
        }
        path.pop_back();    
    }
    
    
    int main()
    {
        int N,K; //N是城市数,K是路的数量   
        string s_city;
        cin>>N>>K>>s_city;    city_num[s_city] = 0; namelist[0] = s_city;
        for(int i =1;i<=N-1;i++) mindis[i] = INT_MAX;
        //接下来的N-1行: 城市名 幸福值
        string city;happy[0] = 0;
        for(int i = 1;i<=N-1;i++ )
        {
            cin>>city>>happy[i];
            city_num[city] = i; //将城市转化为数字序号便于dfs
            namelist[i] = city; 
        }
        
        //接下来存城市之间的距离,用城市序号表示
        string s1,s2;int d;
        int c1,c2;
        while(K--)
        {
            cin>>s1>>s2>>d;
            dis[city_num[s1]][city_num[s2]] = d;
            dis[city_num[s2]][city_num[s1]] = d;
            
            c1 = city_num[s1];c2= city_num[s2];
            v[c1].emplace_back(c2);
            v[c2].emplace_back(c1);
        }
        destination =city_num["ROM"];
        dfs(0,0,0,0);
        cout<<num_way<<" "<<final_dis<<" "<<final_happy<<" "<<final_happy/final_step<<endl;
        cout<<s_city;
        for(unsigned int i = 1;i<final_path.size();i++)
            cout<<"->"<<namelist[final_path[i]];
        return 0;
        
    }

     结果是有一例超时了

    加个快读

    #include<iostream>
    #include<vector>
    #include<unordered_map>
    #include<limits.h>
    using namespace std;
    
    int mindis[201];
    vector <int> path;
    int num_way;//number of the same ways
    int destination;
    string namelist[200];
    int happy[200];
    int dis[200][200];
    vector<int> final_path;
    int final_dis,final_happy,final_step;
    vector<int> v[200];// its neghbor
    unordered_map<string,int>city_num;
    
    
    
    void dfs (int curcity,int curdis,int curhappy,int curstep)
    {
        if( curdis> mindis[curcity]) return;//stop loss
        path.emplace_back(curcity);
        if(curcity == destination)//如果到了终点
        {
            if(curdis < mindis[destination])
            {
                mindis[destination] = curdis;
                final_path = path;
                final_dis = curdis;
                final_happy = curhappy;
                final_step = curstep;
                num_way = 1;
            }
            else  //equal case
            {
                num_way++;
                if(curhappy> final_happy || (curhappy == final_happy && curstep < final_step))
                {
                    final_path = path;
                    final_dis = curdis;
                    final_happy = curhappy;
                    final_step = curstep;
                }
            }
        }
        else // not reach the destination
        {
            if( curdis <  mindis[curdis])
                   mindis[curcity] = curdis;
            for(int each:v[curcity])//find the neighbor
            {
                dfs(each,curdis+dis[curcity][each],curhappy+happy[each],curstep+1);
            }
        }
        path.pop_back();    
    }
    
    
    int main()
    {
        ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
        int N,K; //N是城市数,K是路的数量   
        string s_city;
        cin>>N>>K>>s_city;    city_num[s_city] = 0; namelist[0] = s_city;
        for(int i =1;i<=N-1;i++) mindis[i] = INT_MAX;
        //接下来的N-1行: 城市名 幸福值
        string city;happy[0] = 0;
        for(int i = 1;i<=N-1;i++ )
        {
            cin>>city>>happy[i];
            city_num[city] = i; //将城市转化为数字序号便于dfs
            namelist[i] = city; 
        }
        
        //接下来存城市之间的距离,用城市序号表示
        string s1,s2;int d;
        int c1,c2;
        while(K--)
        {
            cin>>s1>>s2>>d;
            dis[city_num[s1]][city_num[s2]] = d;
            dis[city_num[s2]][city_num[s1]] = d;
            
            c1 = city_num[s1];c2= city_num[s2];
            v[c1].emplace_back(c2);
            v[c2].emplace_back(c1);
        }
        destination =city_num["ROM"];
        dfs(0,0,0,0);
        cout<<num_way<<" "<<final_dis<<" "<<final_happy<<" "<<final_happy/final_step<<endl;
        cout<<s_city;
        for(unsigned int i = 1;i<final_path.size();i++)
            cout<<"->"<<namelist[final_path[i]];
        return 0;
        
    }

    还是超时了,看来,cin是在是扶不起来啊。。。。。。

    同时,这种dfs的方法本身效率太低了,递归层数太多,只能说好写,但是肯定要用其他方法改进

    找最短路,完全可手撕一个迪杰斯特拉算法。

    超时原因有两个:cin cout 流输入输出 和dfs的递归层数,不好处理大数据

    关于最短路解决,可以看这篇博客:

    https://www.cnblogs.com/ranzhong/p/14258677.html

    样例全部通过 了

  • 相关阅读:
    Qt操作xml文件(增删改功能)
    Qt解析xml
    Qt中使用DOM解析XML文件或者字符串二(实例)
    Qt中使用DOM解析XML文件或者字符串(实例)
    QThread 实用技巧、误区----但文档中没有提到
    事件循环与线程 二
    事件循环与线程 一
    第一讲 递归
    Ubuntu 建立桌面快捷方式
    Codeforces554B:Ohana Cleans Up
  • 原文地址:https://www.cnblogs.com/ranzhong/p/14255758.html
Copyright © 2011-2022 走看看