SGU 174 解题手记
用并查集维护所有线段的端点,最初所有的端点都以自己为根,加入一条线段时,若两个端点在同一个集合中,则说明出现“封闭区域”,否则将一个端点的根设置为另外一个。并查集要有路径压缩。
实现上,用map作为并查集的容器。
Submit 1: WA on 2。合并操作写错了。“将一个端点的根设置为另外一个”是不准确的,应该是“将两个端点所在集合合并”。
Submit 2: TLE on 4。常数太大了。
Submit 3: TLE on 4。还是太大,用一个模板吧。
Submit 4: PE on 4。What? 无解的判断写错了。
Submit 5: AC。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include <map> using namespace std; #define MAXN 400000 #define sig(x) ((x)>0?1:-1) #define abs(x) ((x)>0?(x):-(x)) #define _ufind_run(x) for(;p[t=abs(x)];x=sig(x)*p[abs(x)],p[t]=sig(p[t])*(p[abs(x)]?p[abs(x)]:abs(p[t]))) #define _run_both _ufind_run(i);_ufind_run(j) #define _set_side(x) p[abs(i)]=sig(i)*(abs(i)==abs(j)?0:(x)*j) #define _judge_side(x) (i==(x)*j&&i) struct ufind { int p[MAXN],t; ufind(){memset(p,0,sizeof(p));} int set_friend(int i,int j){_run_both;_set_side(1);return !_judge_side(-1);} int set_enemy(int i,int j){_run_both;_set_side(-1);return !_judge_side(1);} int is_friend(int i,int j){_run_both;return _judge_side(1);} int is_enemy(int i,int j){_run_both;return _judge_side(-1);} }; struct point { int x,y; }; bool operator <(const point &a,const point &b) { return (a.x<b.x || a.x==b.x && a.y<b.y); } int main() { map<point,int> points; ufind tland; int i,m; scanf("%d",&m); for (i=0;i<m;++i) { point a,b; scanf("%d%d%d%d",&a.x,&a.y,&b.x,&b.y); if (points.find(a)==points.end()) points[a]=i<<1; if (points.find(b)==points.end()) points[b]=(i<<1)+1; int ida=points[a],idb=points[b]; if (tland.is_friend(ida,idb)) { printf("%d\n",i+1); break; } tland.set_friend(ida,idb); } if (i>=m) printf("0\n"); return 0; } |
12 Responses
建议少用宏定义,容易引起问题..
Reply
这是个模版,可以放心用,不会有错。
Reply
“将一个端点的根设置为另外一个”是不准确的,应该是“将两个端点所在集合合并”。
您好,无意中路过看到这句话,我有一点小问题想请教
合并操作前首先要找出两点的根,判断如果是不同根再合并
而在找两点的根的过程中,已经顺便做了路径压缩吧?
这样的话,合并的时候,两点距离他们原本所在的根深度只有1了
这时再“将一个端点的根设置为另外一个”,会有不准确的情况吗?
因为我原来写并查集一直也是这么写的。。
Reply
“将一个端点的根设置为另外一个”的效果是将某个点移入另外一个集合;“将两个端点所在集合合并”是将某个集合的所有元素移入另外一个集合。
Reply
刚开始还以为我以前写的所有AC过的并查集题莫非都是错的..
看了您的回复结果是我误解您原话的意思了~
没问题了~
:)
Reply
我TLE on 4
你觉得会是qsort的问题,还是并查集的问题
Reply
都有可能,可以用固定变量法确定问题所在。
Reply
我已经过了,是qsort,加了random就好,
但能否讲下什么是固定变量法,具体到本题如何用
Reply
“固定变量法”是开玩笑的,就是用标程中的程序段替换自己的,看看哪一段错了。
Reply
呵呵
Reply
你用了我们的模板啊...
Reply
是否需要将模板代码隐藏?
Reply
Top Seven
Recent Comments
Categories
Blogroll
Login
Sponsor