假设只要处于同一病房内的某两个病人间有仇恨,那么他们一定会在每年的某个时候发生摩擦。那么,应如何分配病人,才能使市长看到的那个冲突事件的影响力最小?(即最和谐)这个最小值是多少?
裸题不解释
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <stack> #include <queue> #define MAXN 55555 #define MAXM 500005 #define INF 1000000005 using namespace std; struct Edge { int v, next; }edge[MAXM * 2]; int n, m, e, head[MAXN]; int top, scc, index; int x[MAXM], y[MAXM], c[MAXM]; int dfn[MAXN], low[MAXN], instack[MAXN], fa[MAXN]; int st[MAXN]; void init() { top = scc = index = e = 0; memset(head, -1, sizeof(head)); memset(instack, 0, sizeof(instack)); memset(dfn, 0, sizeof(dfn)); } void insert(int x, int y) { edge[e].v = y; edge[e].next = head[x]; head[x] = e++; } void tarjan(int u) { int v; instack[u] = 1; dfn[u] = low[u] = ++index; st[++top] = u; for(int i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if(instack[v]) low[u] = min(low[u], dfn[v]); } if(dfn[u] == low[u]) { scc++; do { v = st[top--]; instack[v] = 0; fa[v] = scc; }while(v != u); } } void build(int mid) { for(int i = 1; i <= m; i++) if(c[i] > mid) { insert(x[i], y[i] + n); insert(y[i], x[i] + n); insert(x[i] + n, y[i]); insert(y[i] + n, x[i]); } } bool check() { for(int i = 1; i <= 2 * n; i++) if(!dfn[i]) tarjan(i); for(int i = 1; i <= n; i++) if(fa[i] == fa[i + n]) return false; return true; } void solve() { int low = 0, high = INF, ans = INF; while(low <= high) { int mid = (low + high) >> 1; init(); build(mid); if(check()) {high = mid - 1; ans = min(ans, mid);} else low = mid + 1; } printf("%d\n", ans); } int main() { while(scanf("%d%d", &n, &m) != EOF) { for(int i = 1; i <= m; i++) scanf("%d%d%d", &x[i], &y[i], &c[i]); solve(); } return 0; }