[NOIP2010]关押罪犯(二分+二分图染色)

传送门 大意:我们把图分为两部分,使得两部分中的内部边的最大权值最小。 思路:哎,拿到题的时候想了二分图染色,,发现不好做,但我没有想到二分,只好最后去骗了一个30分。正确的思路是:首先我们要 去二分最大的冲突边的是哪一条(按照权值二分),因为当二分的边权增大时,连的边也就越少,连通块的数目就越多,冲突就越少,所以边权是可以二分的,在二分过后用二分图判定,如果可以染成二分图即为可行的解。

代码:

;int col[MAXN], n, m;struct node{int v, w;node *next;}Edge[MAXM * 2], *Adj[MAXN], *Mcnt = Edge;struct E{int u, v, w;bool operator < (const E rhs) const{return w < rhs.w;}}e[MAXM];void Addedge(int u, int v, int w){node *t = ++Mcnt;t->v = v;t->w = w;t->next = Adj[u];Adj[u] = t;}int ans, mid;bool dfs(int u, int fa){if(col[u] != -1 && col[u] == col[fa]) return 0;if(col[u] == !col[fa]) return 1;col[u] = !col[fa];for(node *p = Adj[u]; p; p = p->next)if(p->v != fa)if(p->w > e[mid].w)if(!dfs(p->v, u))return 0;return 1;}int main(){scanf(“%d%d”, &n, &m);int l = 0, r = m;for(int i = 1; i <= m; i ++)scanf(“%d%d%d”, &e[i].u, &e[i].v, &e[i].w);sort(e + 1, e + m + 1);for(int i = 1; i <= m; i ++){Addedge(e[i].u, e[i].v, e[i].w);Addedge(e[i].v, e[i].u, e[i].w);}while(l <= r){mid = (l + r) >> 1;memset(col, -1, sizeof(int) * (n+2));col[0] = 0;bool flag = 0;for(int i = 1; i <= n; i ++)if(col[i] == -1)if(!dfs(i, 0)){flag = 1;break;}if(flag) l = mid + 1;else {ans = e[mid].w; r = mid – 1;}}printf(“%d\n”, ans);return 0;}

流过泪的眼睛更明亮,滴过血的心灵更坚强!

[NOIP2010]关押罪犯(二分+二分图染色)

相关文章:

你感兴趣的文章:

标签云: