日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu3622 二分+2sat

發布時間:2025/6/17 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu3622 二分+2sat 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ?給你N組炸彈,每組2個,讓你在這N組里面選取N個放置,要求(1)每組只能也必須選取一個(2)炸彈與炸彈之間的半徑相等(3)不能相互炸到對方。求最大的可放置半徑。


思路:

? ? ?二分去枚舉半徑,然后用2sat去判斷是否可行,在2sat里,每組炸彈的兩個是正常對,任何兩組的任何兩個距離小于等于mid那么這兩個是矛盾對。這樣強連通縮短,然后判斷有沒有一組是在同一個強連通塊里的,沒有那么就ok繼續更新二分查找答案。

#include<stdio.h> #include<string.h> #include<math.h> #include<stack>#define N_node 200 + 10 #define N_edge 100000 + 100 using namespace std;typedef struct {int to ,next; }STAR;typedef struct {double x1 ,x2 ,y1 ,y2; }NODE;STAR E1[N_edge] ,E2[N_edge]; NODE node[111]; int list1[N_node] ,list2[N_node] ,tot; int Belong[N_node] ,cnt; int mark[N_node]; stack<int>st;void add(int a , int b) {E1[++tot].to = b;E1[tot].next = list1[a];list1[a] = tot;E2[tot].to = a;E2[tot].next = list2[b];list2[b] = tot; }void DFS1(int s) {mark[s] = 1;for(int k = list1[s] ;k ;k = E1[k].next){int xin = E1[k].to;if(!mark[xin]) DFS1(xin);}st.push(s); }void DFS2(int s) {mark[s] = 1;Belong[s] = cnt;for(int k = list2[s] ;k ;k = E2[k].next){int xin = E2[k].to;if(!mark[xin]) DFS2(xin);} }double diss(double x1 ,double y1 ,double x2 ,double y2) {double tmp = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);return sqrt(tmp); }bool ok(double mid ,int n) {memset(list1 ,0 ,sizeof(list1));memset(list2 ,0 ,sizeof(list2));tot = 1;for(int i = 0 ;i < n ;i ++)for(int j = i + 1 ;j < n ;j ++){int a ,b;double dis = diss(node[i].x1 ,node[i].y1 ,node[j].x1 ,node[j].y1);if(dis <= mid){a = i * 2 ,b = j * 2;add(a ,b^1) ,add(b ,a^1);}dis = diss(node[i].x1 ,node[i].y1 ,node[j].x2 ,node[j].y2);if(dis <= mid){a = i * 2 ,b = j * 2 + 1;add(a ,b^1) ,add(b ,a^1);}dis = diss(node[i].x2 ,node[i].y2 ,node[j].x1 ,node[j].y1);if(dis <= mid){a = i * 2 + 1,b = j * 2;add(a ,b^1) ,add(b ,a^1);}dis = diss(node[i].x2 ,node[i].y2 ,node[j].x2 ,node[j].y2);if(dis <= mid){a = i * 2 + 1,b = j * 2 + 1;add(a ,b^1) ,add(b ,a^1);}}memset(mark ,0 ,sizeof(mark));while(!st.empty())st.pop();for(int i = 0 ;i < n * 2 ;i ++)if(!mark[i]) DFS1(i);memset(mark ,0 ,sizeof(mark));cnt = 0;while(!st.empty()){int xin = st.top();st.pop();if(mark[xin]) continue;++cnt;DFS2(xin);}int mk = 0;for(int i = 0 ;i < n * 2 ;i += 2){if(Belong[i] == Belong[i^1])mk = 1;}return !mk; }int main () {int n ,i;while(~scanf("%d" ,&n)){for(i = 0 ;i < n ;i ++)scanf("%lf %lf %lf %lf" ,&node[i].x1 ,&node[i].y1 ,&node[i].x2 ,&node[i].y2);double low ,mid ,up ,ans = 0;low = 0 ,up = 2000000000;for(i = 1 ;i <= 100 ;i ++){mid = (low + up) / 2;if(ok(mid ,n))ans = low = mid;else up = mid;}printf("%.2lf\n" ,ans/2);}return 0; }

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的hdu3622 二分+2sat的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。