• 所有负权回路的判断


    http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1074

    题目大意:给定路径的关系,问你n个点的最短路,如果最短路的值比3小或无法到达,就输出?

    又做到一个新类型的题目,但是不算太难,就是在spfa发现一个点的更新次数大于n侯进行的更新操作dfs

    因为发现了一个负权回路点后,他直接间接能到的点都会是负权点(就是不存在最短路),而我们一开始用前向星存边也就十分方便了

    多了的就是这个dfs

    void dfs(int u)
    {
        cir[u] = 1;
        for(int i = id[u];~i;i = edge[i].pre)
        {
            if(!cir[edge[i].to])
                dfs(edge[i].to);
        }
    }
    

      其余的就是裸spfa了,默写一遍吧

    #include <iostream>
    #include <vector>
    #include <queue>
    #include <string.h>
    #include <cstdio>
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn = 220;
    int n;
    struct node{
        int to;
        int cost;
        int pre;
        node(int t = 0,int c = 0,int pre = 0):to(t),cost(c),pre(pre){}
    }edge[maxn * maxn];
    int d[maxn];
    int vis[maxn];
    int tim[maxn];
    int busy[maxn];
    int cir[maxn];
    int id[maxn];
    int cnt;
    queue<int>q;
    void init()
    {
        cnt = 0;
        memset(id,-1,sizeof(id));
        memset(vis,0,sizeof(vis));
        memset(tim,0,sizeof(tim));
        memset(cir,0,sizeof(cir));
        while(q.size())q.pop();
    }
    int getcost(int a,int b)
    {
        return (b - a) * (b - a) * (b - a);
    }
    void add(int from,int to,int cost)
    {
        edge[cnt] = node(to,cost,id[from]);
        id[from] = cnt++;
    }
    void dfs(int u)
    {
        cir[u] = 1;
        for(int i = id[u];~i;i = edge[i].pre)
        {
            if(!cir[edge[i].to])
                dfs(edge[i].to);
        }
    }
    void spfa(int s)
    {
        d[s] = 0;
        vis[s] = 1;
        tim[s]++;
        q.push(s);
        while(q.size())
        {
    
            int now = q.front();q.pop();vis[now] = 0;//cout<<now<<endl;
            for(int i = id[now];~i;i = edge[i].pre)
            {
                //cout<<i<<endl;
                int to = edge[i].to;
                if(cir[to])continue;
                if(d[to] > d[now] + edge[i].cost)
                {
                    d[to] = d[now] + edge[i].cost;
                    if(!vis[to])
                    {
                        vis[to] = 1;
                        if(++tim[to] > n)
                        {
                            dfs(to);
                        }
                        else
                        {
                            q.push(to);
                        }
                    }
                }
            }
        }
    }
    int main()
    {
        int t,m,a,b,q;
        scanf("%d",&t);
        int cas = 1;
        while(t--)
        {
            init();
    
            scanf("%d",&n);
            for(int i = 1;i <= n;i++)
            {
                d[i] = inf;
                scanf("%d",&busy[i]);
            }
            scanf("%d",&m);
            for(int i = 1;i <= m;i++)
            {
                scanf("%d%d",&a,&b);
                add(a,b,getcost(busy[a],busy[b]));
            }
            spfa(1);
            printf("Case %d:
    ",cas++);
            scanf("%d",&q);
            while(q--)
            {
                scanf("%d",&a);
                if(cir[a] || d[a] < 3 || d[a] == inf)printf("?
    ");
                else printf("%d
    ",d[a]);
            }
        }
        return 0;
    }
    

     坑了我的是写了init函数,却没有放到main函数里用

  • 相关阅读:
    解决VS在高DPI下设计出的Winform程序界面变形问题
    ribbon 收起 最小化 导航条 选项卡 navBarControl 隐藏
    Devexpress Ribbon Add Logo
    DevExpress控件使用小结 z
    Devexpress中统一设置字体样式的方法
    微信小程序回到顶部的两种方式
    PHP房贷计算器代码,等额本息,等额本金
    java 时间转换
    spark 编译
    mvn常用命令
  • 原文地址:https://www.cnblogs.com/DF-yimeng/p/8561249.html
Copyright © 2020-2023  润新知