例如樣例中小鹿的行程可以是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 ...