求出T条从1到n的路径,要求最长的单条边的长度最短,路径不能重复。
第一感觉就是二分最大路径上限,然后建图,满足条件的边容量设为1,求最大流。
/***************************************** Author :Crazy_AC(JamesQi) Time :2016 File Name : *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; typedef pair<ii,int> iii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 210; const int maxm = 160000 + 10; struct Edge { int from, to, cap, flow, nxt; Edge(){} Edge(int from,int to,int cap, int flow, int nxt) : from(from),to(to),cap(cap),flow(flow),nxt(nxt) {} }edges[maxm]; struct Item { int u, v, cost; }item[maxm]; int dis[maxn]; int head[maxn], ecnt;//链式前向星 int s, t;//源点,汇点 int n, m, T;//点,边 bool spfa(int s,int t) { memset(dis, -1,sizeof dis); dis[s] = 0; queue<int> que; que.push(s); while(!que.empty()) { int u = que.front(); que.pop(); for (int i = head[u];~i;i = edges[i].nxt) { Edge& e = edges[i]; if (e.cap > e.flow && dis[e.to] == -1) { dis[e.to] = dis[u] + 1; que.push(e.to); } } } return dis[t] != -1; } int dfs(int u,int a) { if (u == t || a == 0) return a; int flow = 0, f; for (int i = head[u];~i;i = edges[i].nxt) { Edge& e = edges[i]; if (dis[e.to] == dis[u] + 1 && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0) { flow += f; a -= f; e.flow += f; edges[i^1].flow -= f; if (a <= 0) break; } } if (flow == 0) dis[u] = 0; return flow; } int dinic(int s,int t) { int ret = 0; while(spfa(s, t)) { ret += dfs(s, INF); } return ret; } void Getmap(int mid) { ecnt = 0; memset(head, -1,sizeof head); for (int i = 1;i <= m;++i) { if (item[i].cost <= mid) { edges[ecnt] = Edge(item[i].u, item[i].v, 1, 0, head[item[i].u]), head[item[i].u] = ecnt++; edges[ecnt] = Edge(item[i].v, item[i].u, 0, 0, head[item[i].v]), head[item[i].v] = ecnt++; edges[ecnt] = Edge(item[i].u, item[i].v, 0, 0, head[item[i].u]), head[item[i].u] = ecnt++; edges[ecnt] = Edge(item[i].v, item[i].u, 1, 0, head[item[i].v]), head[item[i].v] = ecnt++; } } } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(~scanf("%d%d%d",&n,&m,&T)) { s = 1, t = n; int high = 0, low = inf; for (int i = 1;i <= m;++i) { scanf("%d%d%d",&item[i].u, &item[i].v,&item[i].cost); high = max(high, item[i].cost); low = min(low, item[i].cost); } high++; int tmp; while(low <= high) { int mid = (low + high) >> 1; Getmap(mid); int ans = dinic(s, t); if (ans >= T) { high = mid - 1; tmp = mid; } else low = mid + 1; } printf("%d\n", tmp); // printf("%d\n", low); // printf("%d\n", high); } return 0; }