zoukankan      html  css  js  c++  java
  • LightOJ

    题意:N个点,分别有属于自己的N个busyness(简称b),两点间若有边,则边权为(ub-vb)^3。Q个查询,问从点1到该点的距离为多少。

    分析:既然是差的三次方,那么可能有负边权的存在,自然有可能出现负环。第一次用Dijkstra做,没多想,样例过了就去交了,结果肯定是WA了。之后加入了对负环的判断。很明显,如果在SPFA的算法过程中,若点u进出队列的次数达到N(N次松弛操作),那么u肯定在负环中。此外,u的邻接点v的距离dist[v]也必然<3,因为dsit[u]可以取到一个极小值。通过dfs函数给这些邻接点也加上标记。最后查询时,若点v不可到达,距离小于3或被标记,都是不合法的情况。

    #include<iostream>
    #include<cstring>
    #include<stdio.h>
    #include<vector>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    using namespace std;
    typedef int LL;
    const int MAXN = 210;
    const int MAXM = MAXN * MAXN;
    const int INF = 0x3f3f3f3f;
    queue<int>q;
    int N,M;
    struct Edge{
        int v,next;
        int w;
    };
    
    struct Spfa
    {
        int N,M;
        bool inq[MAXN];
        int dp[MAXN],cnt[MAXN];
        int pre[MAXN];
        int head[MAXN],tot;
        int dis[MAXN];
        bool incir[MAXN];
        Edge edge[MAXM];
    
        void init(int n){
            N = n;
            tot = 0;
            memset(head,-1,sizeof(head));
            memset(cnt,0,sizeof(cnt));
        }
    
        void Addedge(int u,int v,int w){
            edge[tot].v = v;
            edge[tot].w = w;
            edge[tot].next = head[u];
            head[u] = tot++;
        }
    
        void dfs(int pos){
            incir[pos] = true;
            for (int i = head[pos] ; i != -1 ; i = edge[i].next){
                int v = edge[i].v;
                if (!incir[v])
                    dfs(v);
            }
        }
    
        void spfa(int s){
            memset(incir,false,sizeof(incir));
            memset(inq,false,sizeof(inq));
            for (int i = 1 ; i <= N ; i++) dis[i] = INF;
            while (!q.empty()) q.pop();
            q.push(s);
            dis[s] = 0;
            cnt[s] = 1;
            inq[s] = true;
            while (!q.empty()){
                int u = q.front(); q.pop();
                inq[u] = false;
                for (int i = head[u] ; i != -1 ; i = edge[i].next){
                    int v = edge[i].v;
                    if (incir[v]) continue;
                    if (dis[v] > dis[u] + edge[i].w){
                        dis[v] = dis[u] + edge[i].w;
                        if (!inq[v]){
                            inq[v] = true;
                            cnt[v]++;
                            q.push(v);
                            if (cnt[v] >= N) dfs(v);
                        }
                    }
                }
            }
        }
    }G;
    
    
    LL dist(LL a,LL b){
        LL t = b-a;
        return t*t*t;
    }
    
    LL p[MAXN];
    
    #define LOCAL
    int main()
    {
        #ifdef LOCAL
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
           #endif
        int N,M,S,T,u,v,q,cas=1;
        LL tmp,b;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&N);
            G.init(N);
            for(int i=1;i<=N;++i){
                scanf("%d",&p[i]);
            }
            scanf("%d",&M);
            for(int i=1;i<=M;++i){
                scanf("%d%d",&u,&v);
                G.Addedge(u,v,dist(p[u],p[v]));
            }
            G.spfa(1);
            scanf("%d",&q);
            printf("Case %d:
    ",cas++);
            for(int i=1;i<=q;++i){
                scanf("%d",&v);
                if(G.dis[v]==INF || G.dis[v]<3|| G.incir[v] ) printf("?
    ");
                else printf("%d
    ",G.dis[v]); 
            }
        }  
        return 0;
    }
    为了更好的明天
  • 相关阅读:
    python 魔法方法
    wfst的compose算法
    文法和语言,理解克林闭包
    openfst常用命令
    Longest Substring Without Repeating Characters
    xgboost 实践
    决策树学习
    OPC UA的监控项、订阅、和通知
    限流及常用算法
    本体论与OWL
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9323391.html
Copyright © 2011-2022 走看看