Layout POJ

来源:互联网 发布:foreach遍历二维数组 编辑:程序博客网 时间:2024/06/07 01:16

点击打开链接

两种不等式

1. b-a<=d

2. b-a>=d -> a-b<=-d

注意 题目给的a与b大小关系不确定 坑


个人总结一下

1.1   求差分约束一般都用spfa来求解 (似乎)不可以用djikstra求解

        一般用dijkstra来求最短路时 每次找出一个已经确定的距离且距离最小的点 来松弛其他点 而这些已经确定最短距离的点不会再背松驰

        但这个方法在求最长路时就不成立了 可以考虑这个样例

        4 4

        1 2 2

        2 3 2

        3 4 2

        1 4 3

2.1   如果题目要求一个最大解 即求XXX最多是多少时 要用最短路来求 所有边按照 如果b-a<=c 则构建 a到b 权值为c 的一条边 代表对整个过程施加了 dis[b]<=dis[a]+c 这个限制

        因为在松弛时有   if(dis[v]>dis[u]+w) {dis[v]=dis[u]+w}   就是说当前这一点v的值dis[v]超过了 dis[v]<=dis[u]+w 这个限制 需要将这个值减小

        每点的值都初始化为正无穷 当跑完最短路后 就代表所有限制都被满足后的最大解

2.2   同理 当题目要求最小解时 用最长路来求 所有边按照 如果b-a>=c 则构建 a到b 权值为c 的一条边 代表对整个过程施加了 dis[b]>=dis[a]+c 这个限制

#include <stdio.h>#include <queue>#include <cstring>#include <algorithm>using namespace std;#define ll long long#define N 0x3f3f3f3f3f3f3f3fstruct node{    int v;    ll w;    int next;};queue <int> que;node edge[20010];ll dis[1010];int first[1010],book[1010],cnt[1010];int n,m1,m2,num,flag;void addedge(int u,int v,ll w);void spfa();int main(){    ll w;    int i,u,v,t;    while(scanf("%d%d%d",&n,&m1,&m2)!=EOF)    {        memset(first,-1,sizeof(first));        num=0;        for(i=1;i<=m1;i++)        {            scanf("%d%d%lld",&u,&v,&w);            if(u>v) t=u,u=v,v=t;            addedge(u,v,w);        }        for(i=1;i<=m2;i++)        {            scanf("%d%d%lld",&u,&v,&w);            if(u<v) t=u,u=v,v=t;            addedge(u,v,-w);        }        flag=0;        spfa();        if(flag==1) printf("-1\n");        else if(flag==2) printf("-2\n");        else printf("%lld\n",dis[n]);    }    return 0;}void addedge(int u,int v,ll w){    edge[num].v=v;    edge[num].w=w;    edge[num].next=first[u];    first[u]=num++;    return;}void spfa(){    ll w;    int i,u,v;    while(!que.empty()) que.pop();    memset(dis,0x3f,sizeof(dis));    memset(book,0,sizeof(book));    memset(cnt,0,sizeof(cnt));    que.push(1);    dis[1]=0;    book[1]=1;    cnt[1]++;    while(!que.empty())    {        u=que.front();        que.pop();        book[u]=0;        for(i=first[u];i!=-1;i=edge[i].next)        {            v=edge[i].v,w=edge[i].w;            if(dis[v]>dis[u]+w)            {                dis[v]=dis[u]+w;                if(book[v]==0)                {                    que.push(v);                    book[v]=1;                    cnt[v]++;                    if(cnt[v]>n)                    {                        flag=1;                        return;                    }                }            }        }    }    if(dis[n]==N) flag=2;    return;}