CodeForces - 687D: Dividing Kingdom II (二分图&带权并查集)

Long time ago, there was a great kingdom and it was being ruled by The Great Arya and Pari The Great. These two had some problems about the numbers they like, so they decided to divide the great kingdom between themselves.

The great kingdom consisted of n cities numbered from 1 to n and m bidirectional roads between these cities, numbered from 1 to m. The i-th road had length equal to wi. The Great Arya and Pari The Great were discussing about destructing some prefix (all road with numbers less than some x) and suffix (all roads with numbers greater than some x) of the roads so there will remain only the roads with numbers l, l + 1, ..., r - 1 and r.

After that they will divide the great kingdom into two pieces (with each city belonging to exactly one piece) such that the hardness of the division is minimized. The hardness of a division is the maximum length of a road such that its both endpoints are in the same piece of the kingdom. In case there is no such road, the hardness of the division is considered to be equal to  - 1.

Historians found the map of the great kingdom, and they have q guesses about the l and r chosen by those great rulers. Given these data, for each guess li and ri print the minimum possible hardness of the division of the kingdom.

Input

The first line of the input contains three integers nm and q (1 ≤ n, q ≤ 1000, ) — the number of cities and roads in the great kingdom, and the number of guesses, respectively.

The i-th line of the following m lines contains three integers ui, vi and wi (1  ≤  ui,  vi  ≤  n, 0 ≤ wi ≤ 109), denoting the road number i connects cities ui and vi and its length is equal wi. It‘s guaranteed that no road connects the city to itself and no pair of cities is connected by more than one road.

Each of the next q lines contains a pair of integers li and ri (1  ≤ li ≤ ri ≤ m) — a guess from the historians about the remaining roads in the kingdom.

Output

For each guess print the minimum possible hardness of the division in described scenario.

Example

Input

5 6 55 4 865 1 01 3 382 1 332 4 282 3 403 52 61 32 31 6

Output

-133-1-133

题意:给定N点,M无向边。Q次询问,每次询问给出区间[L,R],现在需要把点集分为两个集合,求最小化集合内的最大边权。

思路:对于这个区间[L,R],从大到小处理,那么就是求二分图,如果假如长度为X的边染色失败,则答案就是X,因为是一条一条的加边,用2-sat不方便,我们用并查集来解决二分图判定。

(不过整体复杂度还是有些玄学)

1<=x<=N表示一色,N+1<=x<=N+N表示二色,4320ms:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1010;
struct in{
    int u,v,w,id;
    bool operator <(const in &x) const { return w>x.w;}
};
in a[maxn*maxn]; int fa[maxn<<1],p[maxn*maxn];
int find(int x){
    if(x!=fa[x]) fa[x]=find(fa[x]); return fa[x];
}
int un(int x,int y){ int fx=find(x),fy=find(y); fa[fx]=fy; }
int main()
{
    int N,M,Q,L,R;
    scanf("%d%d%d",&N,&M,&Q);
    rep(i,1,M) scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w),a[i].id=i;
    sort(a+1,a+M+1);
    rep(i,1,Q){
        int ans=-1; scanf("%d%d",&L,&R);
        rep(j,1,N+N) fa[j]=j;
        rep(j,1,M){
            if(a[j].id<L||a[j].id>R) continue;
            int f1=find(a[j].u),f2=find(a[j].v);
            if(f1==f2){ ans=a[j].w; break; }
            else un(a[j].u+N,a[j].v),un(a[j].u,a[j].v+N);
        }
        printf("%d\n",ans);
    }
    return 0;
}

用带权并查集优化,点全部在1<=x<=N范围内,所以理论上复杂度会降低一半,dis表示点到根的距离奇偶性。2932ms。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1010;
struct in{
    int u,v,w,id;
    bool operator <(const in &x) const { return w>x.w;}
};
in a[maxn*maxn]; int fa[maxn<<1],dis[maxn];
int find(int x){
    if(x!=fa[x]){
        int fx=find(fa[x]);
        dis[x]^=dis[fa[x]];
        fa[x]=fx;
    }
    return fa[x];
}
bool Union(int x,int y){
    int fx=find(x),fy=find(y);
    if(fx==fy){
        if(dis[x]==dis[y]) return false;
        return true;
    }
    fa[fx]=fy; dis[fx]=dis[x]^dis[y]^1;
    return true;
}
int main()
{
    int N,M,Q,L,R;
    scanf("%d%d%d",&N,&M,&Q);
    rep(i,1,M) scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w),a[i].id=i;
    sort(a+1,a+M+1);
    rep(i,1,Q){
        int ans=-1; scanf("%d%d",&L,&R);
        rep(j,1,N) fa[j]=j,dis[j]=0;
        rep(j,1,M){
            if(a[j].id<L||a[j].id>R) continue;
            if(!Union(a[j].u,a[j].v)) { ans=a[j].w; break; }
        }
        printf("%d\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/9559603.html

时间: 2024-10-06 10:58:05

CodeForces - 687D: Dividing Kingdom II (二分图&带权并查集)的相关文章

codeforces 687D Dividing Kingdom II 带权并查集(dsu)

题意:给你m条边,每条边有一个权值,每次询问只保留编号l到r的边,让你把这个图分成两部分 一个方案的耗费是当前符合条件的边的最大权值(符合条件的边指两段点都在一个部分),问你如何分,可以让耗费最小 分析:把当前l到r的边进行排序,从大到小,从大的开始不断加边,判断当前能否形成二分图,如果能形成二分图,继续加边 如果不能形成二分图,那当前边的权值就是最小耗费(是不是很眼熟) 思路很清晰,现在我们要解决的是如何判断可以形成二分图,有两种,一个是2染色当前图(肯定超时) 所以只剩一种方法,带权并查集

UVA - 10004 Bicoloring(判断二分图——交叉染色法 / 带权并查集)

d.给定一个图,判断是不是二分图. s.可以交叉染色,就是二分图:否则,不是. 另外,此题中的图是强连通图,即任意两点可达,从而dfs方法从一个点出发就能遍历整个图了. 如果不能保证从一个点出发可以遍历整个图,那么编程要注意了,应该从每个点出发遍历一次. s2.带权并查集来判断,略复杂.先略过.先上个博客:http://blog.csdn.net/zsc09_leaf/article/details/6727622 c.邻接矩阵,bfs #include<iostream> #include&

hdu 1829 &amp;amp;poj 2492 A Bug&amp;#39;s Life(推断二分图、带权并查集)

A Bug's Life Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8528    Accepted Submission(s): 2745 Problem Description Background  Professor Hopper is researching the sexual behavior of a rare

BZOJ4025 二分图 分治 并查集 二分图 并查集按秩合并 带权并查集

原文链接http://www.cnblogs.com/zhouzhendong/p/8683831.html 题目传送门 - BZOJ4025 题意 有$n$个点,有$m$条边.有$T$个时间段.其中第$i$条边连接节点$x_i,y_i$,并且在$start_i$时刻出现,在$end_i$时刻消失.问每一个时刻的图是不是二分图. $n\leq 10^5,m\leq 2\times 10^5,T\leq 10^5$ 题解 真是一道好题. 做这题我才发现我从来没写过按秩合并的并查集QAQ. 先考虑按

Lightoj1009 Back to Underworld(带权并查集)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Back to Underworld Time Limit:4000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Description The Vampires and Lykans are fighting each other to death. The war has become so fierc

hdu 5441 Travel 离线带权并查集

Travel Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5441 Description Jack likes to travel around the world, but he doesn’t like to wait. Now, he is traveling in the Undirected Kingdom. There are n cities and m

CF1167C News Distribution 带权并查集

https://codeforces.com/contest/1167/problem/C 题意:n个用户有m个分组,每个用户可以在多个分组里出现,也允许某个分组为空.每个用户可以把消息传递到同组的每个人,求每个用户最多把消息传递给多少个人. 思路: 带权并查集,一棵树上的任意一个人都可以把消息传递给树上的其他所有人. rk数组维护该点所属的树拥有多少个结点(包括root). 输出每个结点的rk值即为答案 #include<bits/stdc++.h> using namespace std;

hdu3038(带权并查集)

题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=3038 题意: n表示有一个长度为n的数组, 接下来有m行形如x, y, d的输入, 表示从第x,个元素到第y个元素的和为d(包括x, 和y), 问m行输入里面有几个是错误的(第一个输入是正确的); 思路: 很显然带权并查集咯,我们可以用距离的概念代替和的概念比较好理解一点,d表示x到y的和即x到y的距离; 可以用rank[x]表示x到其父亲节点的距离,  将正确的距离关系合并到并查集中

【POJ1182】 食物链 (带权并查集)

Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类. 第二种说法是"2 X Y",表示X吃Y. 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的.当一句话满足下列三条之