• [CCF CSP]201712-4 行车路线


    暴力+剪枝 只得了40分...暂时没想到正解(好吧,查了一下正解dijkstra

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const ll N=500+10;
    const ll INF=0x3f3f3f3f;
    ll n,m;
    struct edge{
        ll type;
        ll to;
        ll w;
        edge(){}
        edge(ll t,ll b,ll c){type=t;to=b;w=c;}
    };
    vector<edge> g[N];
    ll vis[N],d[N];
    ll t,a,b,c,ans;
    void dfs(ll u,ll pre,ll flag,ll sum,ll x)//x为已走小道长度
    {
        if(sum>ans) return;
        if(sum>=d[u]) return;
        if(u==n)
        {
            ans=min(sum,ans);
            return;
        }
        for(ll i=0;i<g[u].size();i++)
        {
            ll v=g[u][i].to,w=g[u][i].w;
            if(v==pre) continue;
            if(vis[v]) continue;
            vis[v]=1;
            ll f=g[u][i].type,t_sum,xx;
            if(f==0)
            {
                t_sum=sum+w;
                xx=0;
            }
            else {
                t_sum=sum-x*x;
                xx=x+w;
                t_sum+=xx*xx;
            }
            dfs(v,u,f,t_sum,xx);
            vis[v]=0;
        }
        d[u]=min(d[u],sum);
    }
    int main()
    {
        //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        scanf("%lld%lld",&n,&m);
        for(ll i=0;i<m;i++)
        {
            scanf("%lld%lld%lld%lld",&t,&a,&b,&c);
            g[a].push_back(edge(t,b,c));
            g[b].push_back(edge(t,a,c));
        }
        ans=INF;
        memset(vis,0,sizeof(vis));
        memset(d,INF,sizeof(d));
        vis[1]=1;
        dfs(1,-1,0,0,0);
        printf("%lld
    ",ans);
        return 0;
    }
    /*
    6 7
    1 1 2 3
    1 2 3 2
    0 1 3 30
    0 3 4 20
    0 4 5 30
    1 3 5 6
    1 5 6 1
    */

     下面是100分代码,虽然题中说答案不超过1e6,但是不保证其他点到点1的距离不爆int。。还是都改为longlong吧,不然只有80分

    思路就是在dijkstra算法,维护未选中点到源点距离时,判断一下边的类型,并且队列中每个点记录其是通过哪种类型的边过来的以及如果是小道,已走过的长度是多少。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb(x) push_back(x)
    const ll N=510;
    const ll INF=0x3f3f3f3f;
    ll n,m;
    struct Edge{
        ll k;
        ll to;
        ll w;
        Edge(){}
        Edge(ll a,ll b,ll c){k=a;to=b;w=c;}
    };
    struct Node{
        ll num;
        ll dis;
        ll f;
        ll x;
        Node(){}
        Node(ll a,ll b,ll c,ll d){num=a;dis=b;f=c;x=d;}
    };
    vector<Edge> g[N];
    priority_queue<Node> que;
    bool operator<(const Node&a,const Node&b){
        return a.dis>b.dis;
    }
    ll dis[N],vis[N];
    void dijkstra()
    {
        memset(dis,INF,sizeof(dis));
        memset(vis,0,sizeof(vis));
        while(!que.empty()) que.pop();
        dis[1]=0;
        que.push(Node(1,0,0,0));
        while(!que.empty())
        {
            Node now=que.top();
            que.pop();
            ll u=now.num,f=now.f,x=now.x;
            if(vis[u]) continue;
            //cout<<"arrive"<<u<<endl;
            vis[u]=1;
            if(u==n) return;
            for(ll i=0;i<g[u].size();i++)
            {
                ll v=g[u][i].to;
                if(vis[v]) continue;
                ll temp,w=g[u][i].w,k=g[u][i].k;
                if(k==0)
                {
                    temp=dis[u]+w;
                    if(temp<dis[v]){
                        dis[v]=temp;
                        que.push(Node(v,temp,0,0));
                    }
                }
                else if(k==1)
                {
                    if(f==1) {
                        temp=dis[u]-x*x+(x+w)*(x+w);
                        if(temp<dis[v]){
                            dis[v]=temp;
                            que.push(Node(v,temp,1,x+w));
                        }
                    }
                    else{
                        temp=dis[u]+w*w;
                        if(temp<dis[v]){
                            dis[v]=temp;
                            que.push(Node(v,temp,1,w));
                        }
                    }
                }
                //cout<<" update"<<v<<" "<<dis[v]<<endl;
            }
        }
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        ll t,a,b,c;
        for(ll i=0;i<m;i++)
        {
            scanf("%lld%lld%lld%lld",&t,&a,&b,&c);
            g[a].pb(Edge(t,b,c));
            g[b].pb(Edge(t,a,c));
        }
        dijkstra();
        printf("%lld
    ",dis[n]);
        return 0;
    }
  • 相关阅读:
    E. Arranging The Sheep
    B. Box Fitting
    E. Permutation by Sum
    D. Corrupted Array
    联通 F677V2 光猫改桥接
    IntelliJ IDEA 常用快捷键整理
    Git 常用命令速查表
    Git 入门操作指南
    Anaconda 常用命令总结
    VS code 快捷键整理
  • 原文地址:https://www.cnblogs.com/Andrew-aq/p/12500735.html
Copyright © 2020-2023  润新知