POJ3169レイアウト(差分制約アプリケーション+ SPFA)

トピックリンク

説明

他のみんなと同じように、牛は餌を求めて列を作るときに友達の近くに立つのが好きです。FJには、1…Nの番号が付けられたN頭(2 <= N <= 1,000)の牛が直線に沿って立って餌を待っています。牛は番号付けされた順序で立っており、かなり押し付けがましいため、2頭以上の牛がまったく同じ場所に並んでいる可能性があります(つまり、各牛が配置されていると考えると)数直線上のある座標では、2頭以上の牛が同じ座標を共有する可能性があります)。

一部の牛はお互いが好きで、一列に並んでお互いの特定の距離内にいたいと思っています。お互いが本当に嫌いで、少なくとも一定の距離を隔てたいと思う人もいます。ML(1 <= ML <= 10,000)制約のリストには、どの牛がお互いに好きか、およびそれらを分離できる最大距離が記載されています。後続のMD制約のリスト(1 <= MD <= 10,000)は、どの牛がお互いを嫌うか、およびそれらを分離する必要がある最小距離を示します。

あなたの仕事は、可能であれば、距離の制約を満たす、牛1と牛Nの間の可能な最大距離を計算することです。
————————————————
入力
行1:3つのスペースで区切られた整数:N、ML、およびMD。

2行目…ML + 1:各行には、スペースで区切られた3つの正の整数A、B、Dが含まれ、1 <= A <B <= Nです。牛AとBは最大でD(1 <= D < = 1,000,000)離れています。

行ML + 2…ML + MD + 1:各行には、スペースで区切られた3つの正の整数A、B、およびDが含まれ、1 <= A <B <= Nです。牛AおよびBは少なくともD(1 <= D <= 1,000,000)離れています。
————————————————
出力
行1:単一の整数。ラインナップできない場合は-1を出力します。牛1とNを任意に離すことができる場合は、-2を出力します。それ以外の場合は、牛1とNの間の可能な最大距離を出力します
。————————————————
サンプル入力
4 2 1
1 3 10
2 4 20
2 3 3

サンプル出力
27
(以前は差分制約を学習していなかったため、今では時間がかかります。QAQ)

アイデア

この質問は、差分制約と負のリングの組み合わせです。ab<= x; cd> = yの場合、2つの式の符号が異なるため、結果をより便利にするためにいくつかの変更を加える必要があることがわかります。式に-1を掛けると、dc <=-yになります。このような不等式の条件下では、SPFAを使用して最短パスを取得できます。

コード

#include<map>
#include<stack>
#include<queue>
#include<string>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define pb push_back
using namespace std;
const int maxn=1e5+5;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
bool vis[maxn];
int n,m,k,u,v,w,dis[maxn],num[maxn];
struct node
{
    
    
	int v,w;
};
queue<int>que;
vector<node>a[maxn];
void spfa()
{
    
    
	memset(num,0,sizeof num);
	memset(dis,inf,sizeof dis);
	memset(vis,false,sizeof vis);
	dis[1]=0;
	num[1]++;
	que.push(1);
	while(!que.empty())
	{
    
    
		int u=que.front();
		vis[u]=false;
		que.pop();
		for(int i=0;i<a[u].size();i++)
		{
    
    
			int v=a[u][i].v,w=a[u][i].w;
			if(dis[v]>dis[u]+w)
			{
    
    
				dis[v]=dis[u]+w;
				if(!vis[v])
				{
    
    
					num[v]++;
					if(num[v]>=n)
					{
    
    
						cout<<"-1"<<endl;
						return ;
					}
					que.push(v);
					vis[v]=true;
				}
			}
		}
	}
	if(dis[n]==inf)
		cout<<"-2"<<endl;
	else
		cout<<dis[n]<<endl;
	return ;
}
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>k;
    for(int i=0;i<m;i++)
    {
    
    
    	cin>>u>>v>>w;
    	a[u].pb({
    
    v,w});
    	a[v].pb({
    
    u,w});
	}
	for(int i=0;i<k;i++)
	{
    
    
		cin>>u>>v>>w;
		a[v].pb({
    
    u,-w});
	}
	spfa();
    return 0;
}

おすすめ

転載: blog.csdn.net/WTMDNM_/article/details/108682282