acdrem1083 人民城管愛人民 DP

2021-07-27 21:24:30 字數 1672 閱讀 3506

思路:d(i, 0)表示從節點i到達大運村的最短路徑,d(i, 1)表示從節點i到達大運村的次短路徑。

1.最短路:當做dag處理即可。

2.次短路:假設當前在u點處,下乙個節點是v。v到終點的最短路是d(v, 0),次短路是d(v, 1),u到v的距離是w(u, v),只能封鎖一條路,即只能刪除一條邊。分成兩種情況:

a.將封鎖用在了v點到達終點的路上,則此時gg擁有主動權,可以選擇最小的路徑,即imin = min(w(u, v) + d(v, 1)),;

b.將封鎖用在u-v這條路徑上面,則此時城管擁有主動權,可以封鎖最短路徑,則gg這能選擇次短路徑hmin。

則d(u, 1) = max(imin, hmin)

ac**

#include #include #include #include #include #include #include #include #include #include #include #include using namespace std;

#pragma comment(linker, "/stack:1024000000,1024000000")

#define eps 1e-10

#define inf 0x3f3f3f3f

#define pi pairtypedef long long ll;

const int maxn = 10000 + 5;

int n, m;

int d[maxn][2], in[maxn], top[maxn], c[maxn*20];

struct edge

edge(int u, int v, int d, int ne):from(u), to(v), dist(d), nex(ne){}

}edge[maxn*20];

int edgenum, head[maxn];

void add_edge(int u, int v, int dis)

void topsort()

top[num++] = u; }}

void solve(int u) //終點

int num = 0, imin = inf;

for(int i = head[u]; i != -1; i = edge[i].nex) if(!(i&1))

if(num < 2) //gg無法到達從u到達終點

int fir = c[0], sec = c[1]; //最小和次小

if(fir > sec) swap(fir, sec);

for(int i = 2; i < num; ++i)

else sec = min(sec, c[i]);

} d[u][1] = max(imin, sec);

if(d[u][1] > inf) d[u][1] = inf;

if(d[u][0] > inf) d[u][0] = inf;

}int main()

topsort();

for(int i = 0; i < n; ++i)

if(d[0][1] >= inf) printf("-1\n");

else printf("%d\n", d[0][1]);

} return 0;

}

如有不當之處歡迎指出!

99年人民幣冠號大全

99版5元券 107種 第一大組 ag ah ai aj ba bb bc bd be bf bg bh bi bj ca cb cc cd ce cf cg ch ci cj da db dc dd de df dg dh di dj ea eb ec ed ee ef eg eh ei ej f...

面試題精選(70) 100人民幣問題

題目描述 用1元,2元,5元,10元,20元和50元的紙幣組成100元,共有多少種情況。要求輸出總方案數和每種方案中各紙幣的個數。4562種 揹包解法 include using namespace std define n 6 int w n int number used n bool is u...

2012 人民搜尋 實習生招聘 筆試題

1 列印漢諾塔移動步驟,並且計算複雜度。方法是遞迴,將n 1層移到中間柱,然後將最底層移到目標柱,然後再把n 1層移到目標柱。f n 2f n 1 1 f 1 1 f n 1 2 f n 1 1 f n 2 n 1 t n o 2 n 2 計算兩個字串的是否相似 字元的種類,和出現次數相同 先比較s...