• poj2983


    题意:给出两种关于防御站位置的信息,一种是确切的信息,P A B X,表示a在b北面x距离的地方,另一种是V A B,表示只知道A在B的北面。问这些信息有没有矛盾。

    分析:差分约束。第一种记为A-B>=X && A-B<=X,第二种记为A-B>=0,用SPFA求得解,则没有矛盾,否则就有矛盾。

    #include <iostream>
    #include <stdio.h>
    #include <queue>
    using namespace std;
    const int N=1001;
    const int E=2*100000+1000;
    const int inf=10000000;
    struct edge{
        int to,w,next;
    };
    int adj[N];
    edge e[E];//存放顶点的所有邻接边
    bool visit[N];
    int d[N];
    /*记录节点更新的次数,如果超过n次,说明存在回路
    由于约束图中含有n+1个顶点,所以每个顶点被松弛的次数不能能超过n
    */
    int cnt[N];
    int edge_num=0,n=0,m=0;
    bool spfa()
    {
        int s,u,v,i,w;
        s=0;
        queue<int> q;
        for(i=0;i<=n;i++)
            visit[i]=false;
        for(i=0;i<=n;i++)
            cnt[i]=0;
        visit[s]=true;
        q.push(s); //将源点加入到队列中
        while(!q.empty())
        {
            u=q.front();
        //    cout<<"出队:"<<u<<endl;
            q.pop();
            visit[u]=false;
            //遍历u的所有邻接边
            for(i=adj[u];i!=-1;i=e[i].next)
            {
                v=e[i].to;
                w=e[i].w;
        //        cout<<"v"<<v<<endl;
                if(d[u]+w < d[v])
                {
                    d[v]=d[u]+w;
                    if(!visit[v])
                    {
                        visit[v]=true;
                        q.push(v);
                        cnt[v]++;
                        if(cnt[v]>n) //更新不超过n,有n+1个顶点,一开始写成>=n了
                        {
                        //    delete []visit;
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
    int main()
    {
        char ch;
        int i,u,v,w;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            edge_num=0;
            for(i=0;i<=n;i++)
            {
                adj[i]=-1;
                d[i]=inf;
            }
            d[0]=0;
            for(i=0;i<m;i++)
            {
                cin>>ch;
                if(ch == 'P')
                {
                    scanf("%d%d%d",&u,&v,&w);
                    e[edge_num].to=u;
                    e[edge_num].w=w;
                    e[edge_num].next=adj[v];
                    adj[v]=edge_num++;
    
                    e[edge_num].to=v;
                    e[edge_num].w=(-1)*w;
                    e[edge_num].next=adj[u];
                    adj[u]=edge_num++;
                }
                else
                {
                    //x1-x2>=1,转化为约束条件为x2-x1<=-1
                    scanf("%d%d",&u,&v);
                    e[edge_num].to=v;
                    e[edge_num].w=-1;
                    e[edge_num].next=adj[u];
                    adj[u]=edge_num++;
                }
            }
            //添加源点到其他顶点的边,权值为0
            for(i=1;i<=n;i++)
            {
                e[edge_num].to=i;
                e[edge_num].w=0;
                e[edge_num].next=adj[0];
                adj[0]=edge_num++;
            }
            if(!spfa())
                printf("Unreliable\n");
            else
                printf("Reliable\n");
        }
        return 0;
    }
  • 相关阅读:
    javascript基础
    杂谈
    六大设计原则
    MVC的理解
    不错的资源哦
    平时你从哪里获取前端知识?
    网站背景平铺
    js 获取节点
    自适应后的页面用户点击后会放大
    innerHTML的运用
  • 原文地址:https://www.cnblogs.com/ZShogg/p/3053944.html
Copyright © 2020-2023  润新知