Layout

源代码:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct Node
{
    int S,To,Next;
}Edge[20001];
deque <int> Q;
int n,m1,m2,Num,i[1001],Sum[1001],Head[1001];
bool In[1001]={0};
void Add(int t1,int t2,int t) //边表。
{
    Edge[++Num].S=t;
    Edge[Num].To=t2;
    Edge[Num].Next=Head[t1];
    Head[t1]=Num;
}
bool SPFA() //SPFA+SLF。
{
    i[1]=0;
    In[1]=true;
    Q.push_back(1);
    while (!Q.empty())
    {
        int t=Q.front();
        In[t]=false;
        Q.pop_front();
        for (int a=Head[t];a;a=Edge[a].Next)
        {
            int T=Edge[a].To;
            if (i[T]>i[t]+Edge[a].S)
            {
                Sum[T]=Sum[t]+1;
                if (Sum[T]>n)
                  return true;
                i[T]=i[t]+Edge[a].S;
                if (!In[T])
                {
                    In[T]=true;
                    if (!Q.empty()&&i[T]>i[Q.front()])
                      Q.push_front(T);
                    else
                      Q.push_back(T);
                }
            }
        }
    }
    return false;
}
void Solve() //差分约束系统。
{
    Num=0;
    memset(i,0x3f,sizeof(i));
    memset(Sum,0,sizeof(Sum));
    memset(Head,0,sizeof(Head)); //注意初始化。
    for (int a=0;a<m1;a++)
    {
        int t,t1,t2;
        scanf("%d%d%d",&t1,&t2,&t);
        Add(min(t1,t2),max(t1,t2),t); //编号性质。
    }
    for (int a=0;a<m2;a++)
    {
        int t,t1,t2;
        scanf("%d%d%d",&t1,&t2,&t);
        Add(max(t1,t2),min(t1,t2),-t); //变号。
    }
    if (SPFA()) //存在负环 
      printf("-1\n");
    else
      if (i[n]==i[0])
        printf("-2\n");
      else
        printf("%d\n",i[n]);
}
int main()
{
    while (scanf("%d%d%d",&n,&m1,&m2)==3) //坑人的多组数据!
      Solve();
    return 0;
}

/*
    因为是队列,所以编号是单调递增的,只需要区分符号,再SPFA即可。
*/
posted @ 2016-11-09 20:44  前前前世。  阅读(176)  评论(0编辑  收藏  举报