bzoj4427【Nwerc2015】Cleaning Pipes清理管道
生活随笔
收集整理的這篇文章主要介紹了
bzoj4427【Nwerc2015】Cleaning Pipes清理管道
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
Link?ping有一個相當復雜的水資源運輸系統。在Link?ping周圍的出水點有一些水井。這些水通過管道輸送到其它地點。每條管道是從某一個水井到城市的某個位置的直線管道。 所有管道在地下的深度相同。因此,無論何時,兩個管道相交時,它們會形成交點。幸運的是,管道系統正好是以滿足兩個管道有交點的方式建造。井不計入交點。任何數量的管道(包括零個與超過兩個)都可以來源于每一個水井。 這些交點導致了一個問題,因為污垢(石灰和其它東西的混合物)往往會卡住交點,導致管道崩潰和坍塌,導致大型水槽孔的形成。這樣的水槽孔對Link?ping的學生有吸引的效果,使他們荒廢學業,不受教育,這從長遠來看將不只是導致管道系統的崩潰,還有社會的結構。因此,當務之急是管道定期清理。北歐提水再分配公司(NWERC) -負責Link?ping的水管的 – 擁有充足的機器人車隊才可以完成此任務。一個機器人可以在一條管道的開始位置被插入。然后,機器人通過管道一直到結束,并清除沿途所有交點。到達終點后,機器人轉身并返回它開始的井。為了防止機器人互相碰撞,政府法規規定每當兩個管相交,它們中的至多一個可以包含一個機器人。 由于整個水系統在被清潔時必須關閉(另一政府法規),則NWERC想迅速完成清洗,使用一批次清潔機器人,都必須在同一時間開始。 你的任務是驗證是否可以做到這一點 - 即,是否能夠把機器人同時插入管道中的一些,在不會有兩個機器人相撞的危險下清潔所有交點。輸入格式
輸入包括: 第一行兩個整數w(1<=w<=1000)和p(1<=p<=1000),分別表示井的數量和管道的數量。 接下來w行,每行兩個整數xi和yi(-10000<=x,y<=10000),表示i號井的位置(井從1到w編號)。 接下來p行,每行3個整數s(1<=s<=w)表示管道從s號井開始,x和y(-10000<=x,y<=10000)表示管道在位置為x,y的點結束。 每條管道都有一個井,就是它開始的那個。被兩個或多個管道共享的點是一口井。任兩條管道至多會有一個交點。兩條管道的公共點可以是他們其中之一或兩者的端點。所有管道的長度為正數。輸出格式
If it is possible to clean all intersections as described above, output “possible”. Otherwise, output “impossible”. 如果在上述情況下可以清理所有交點,輸出“possible”,否則輸出“impossible”。-
題解:
- 題目意思一些射線,端點不算交點,相交的射線只能放一個機器人,問是否有方案讓每一個交點都被機器人經過;
- 如果A和B有交點,那么A放B不放,A不放B一定放,(多個交于一點也是符合題意的),轉化成2-sat求解;
- 翻閱了官解,發現如果有交點A和B連邊,二分圖判定(因為合法的方案對應了二分圖的某一邊的點集);
- 1 #include<bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4 const int N=1010;
5 int n,m,tot,id[N][2],o=1,hd[N<<1],dfn[N<<1],low[N<<1],idx,st[N<<1],top,bl[N<<1],del[N<<1],cnt;
6 struct Edge{int v,nt;}E[N*N*2];
7 struct point{
8 int x,y;
9 point(int _x=0,int _y=0):x(_x),y(_y){};
10 point operator +(const point&A)const{return point(x+A.x,y+A.y);}
11 point operator -(const point&A)const{return point(x-A.x,y-A.y);}
12 bool operator ==(const point&A)const{return x==A.x&&y==A.y;}
13 int operator *(const point&A)const{return x*A.x+y*A.y;}
14 int operator ^(const point&A)const{return x*A.y-y*A.x;}
15 }p[N];
16 struct line{point a,b;}l[N];
17 void Adde(int u,int v){E[o]=(Edge){v,hd[u]};hd[u]=o++;}
18 void tarjan(int u){
19 dfn[st[++top]=u]=low[u]=++idx;
20 for(int i=hd[u];i;i=E[i].nt){
21 int v=E[i].v;
22 if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]);
23 else if(!del[v])low[u]=min(low[u],dfn[v]);
24 }
25 if(dfn[u]==low[u]){
26 int v;cnt++;
27 do{
28 bl[v=st[top--]]=cnt;
29 del[v]=1;
30 }while(v!=u);
31 }
32 }
33 bool judge(int i,int j){
34 if(l[i].a==l[j].a)return false;
35 point a=l[j].a-l[i].a,b=l[j].b-l[i].a,c=l[i].b-l[i].a;
36 if((ll)(c^a)*(c^b)>0)return false;
37 b=l[j].a-l[i].b,c=l[j].b-l[j].a;
38 if((ll)(c^a)*(c^b)>0)return false;
39 return true;
40 }
41 int main(){
42 #ifndef ONLINE_JUDGE
43 freopen("bzoj4427.in","r",stdin);
44 freopen("bzoj4427.out","w",stdout);
45 #endif
46 scanf("%d%d",&n,&m);
47 for(int i=1;i<=n;i++)scanf("%d%d",&p[i].x,&p[i].y);
48 for(int i=1,x;i<=m;i++){
49 scanf("%d",&x);l[i].a=p[x];
50 scanf("%d%d",&l[i].b.x,&l[i].b.y);
51 id[i][0]=++tot;id[i][1]=++tot;
52 }
53 for(int i=1;i<=m;i++)
54 for(int j=i+1;j<=m;j++)if(i!=j&&judge(i,j)){
55 Adde(id[i][0],id[j][1]);
56 Adde(id[i][1],id[j][0]);
57 Adde(id[j][0],id[i][1]);
58 Adde(id[j][1],id[i][0]);
59 }
60 for(int i=1;i<=tot;i++)if(!dfn[i])tarjan(i);
61 int fg=0;for(int i=1;i<=m;i++)if(bl[id[i][0]]==bl[id[i][1]]){fg=1;break;}
62 puts(fg?"impossible":"possible");
63 return 0;
64 } bzoj4427
?
轉載于:https://www.cnblogs.com/Paul-Guderian/p/10269213.html
總結
以上是生活随笔為你收集整理的bzoj4427【Nwerc2015】Cleaning Pipes清理管道的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java通过Pattern类使用正则表达
- 下一篇: 孙正义投资了哪些公司 真正的投资帝国