51 Nod 1326 遙遠的旅途

2021-07-26 18:28:32 字數 1438 閱讀 7414

例如樣例中小鹿的行程可以是0->1->2->0->2.

這題長得很像乙個完全揹包,但是是在乙個圖上面的。

因為一條邊很可能會重複走,那麼連向n的邊肯定有一條至少走一次,所以與n相連的邊的重複可能性最大。(其他有重複也沒有關係,下面會講)

我們考慮在走到n之後,然後在與n連線的一條邊上不斷地折返,最後時間到達t。那麼就是要求前面到達n的距離和為a,折返的這條邊長為w,那麼要求(t

−a)mod2w

=0。如果存在possbie方案的話,那麼這種方案一定合法。後面證明。

為了求到a,所以我們要用dp來推。 因為t

−a≡0

(mod2w

) ,所以

tmod2w

=amod2w

所以我們設f[i][j]為走到第i個點,然後距離f[i][j] mod 2w=j的最小的f[i][j],那麼dp轉移很顯然。

那麼我們列舉每一條連向n的邊為w,然後做一遍dp,如果求得的f[n][t%2w]≤t,那麼說明到達n之後還有折返w這條邊的機會一次到達t這個時間。

那麼求f的時候,就已經考慮了除了最後在w折返的其他的環、折返等情況,因為是暴力dp。

那麼怎麼優化這個dp呢?

因為dp的轉移式是最短路,所以用spfa優化就好了。

#include

#include

#include

#include

#include

#define fo(i,a,b) for(i=a;i<=b;i++)

#define rep(i,a) for(i=first[a];i;i=next[i])

using namespace std;

typedef long long ll;

const int maxn=57;

int i,j,k,l,n,m,ans,cas,x,y,z,w;

ll t,f[maxn][20007];

bool cz,bz[maxn][20007];

int num,first[maxn*2],next[maxn*2],last[maxn*2],chang[maxn*2];

int a[maxn],data[200007][2];

void add(int

x,int

y,int z)

void dfs(int

x,ll y)

}}void spfa()}}

bz[now][b]=0;

}}int main()

cz=0;

a[0]=0;

rep(i,n)a[++a[0]]=chang[i];

fo(k,1,a[0])

if(cz)printf("possible\n");else

printf("impossible\n");

}}

51nod1326 遙遠的旅途

給你乙個n個點m條邊的無向圖,每條邊有正整數的邊權,問是否存在一條0到n 1的長度為t的路徑 點和邊可以重複 n,m 50 邊權不超過10000 t 1018 資料組數不超過3 這道題有點考思維啊!考慮這樣的一條路徑。如果不是簡單路徑,它可能會包括若干個環。如果我確定了乙個必須走的環,假設它的長度為...

51nod1326 遙遠的旅途

一張有n個點,m條變的無向圖,每條邊有邊權。在0時刻有乙個人在點1,每一次他走過一條邊,消耗的時間為這條邊的邊權,而不能停留在原地。現在他想知道是否存在一種方案使得他在t時刻剛好到達點n。多組資料,case 3,2 n 50,1 m 50,1 t 10 18 上上週做gdoi組時worldwide ...

51Nod 1326 遙遠的旅途

解題報告 用時 1h30min,1tle 這題首先要明白,到終點至少要經過一條n的出邊,所以如果可行,一定是將某一條出邊走很多次,然後再到達終點,即 2 w j t 所以只要 j t mod2 w 存在即可,所以我們列舉每一條出邊,然後跑spfa 看 f n j 是否存在即可,我們定義 f i j ...