2010 Asia Regional Tianjin Site —— Online Contest (线段树二维转一维,2-SAT,floyed变形)hdu3621-3631

来源:互联网 发布:csgo残局 知乎 编辑:程序博客网 时间:2024/04/26 08:40

Bomb Game

Problem Description

Robbie is playing an interesting computer game. The game field is an unbounded 2-dimensional region. There are N rounds in the game. At each round, the computer will give Robbie two places, and Robbie should choose one of them to put a bomb. The explosion area of the bomb is a circle whose center is just the chosen place. Robbie can control the power of the bomb, that is, he can control the radius of each circle. A strange requirement is that there should be no common area for any two circles. The final score is the minimum radius of all the N circles.
Robbie has cracked the game, and he has known all the candidate places of each round before the game starts. Now he wants to know the maximum score he can get with the optimal strategy.

Input

The first line of each test case is an integer N (2 <= N <= 100), indicating the number of rounds. Then N lines follow. The i-th line contains four integers x1i, y1i, x2i, y2i, indicating that the coordinates of the two candidate places of the i-th round are (x1i, y1i) and (x2i, y2i). All the coordinates are in the range [-10000, 10000].

Output

Output one float number for each test case, indicating the best possible score. The result should be rounded to two decimal places.

Sample Input

2
1 1 1 -1
-1 -1 -1 1
2
1 1 -1 -1
1 -1 -1 1

Sample Output

1.41
1.00
思路:对于这2*N个点,如果两个点之间“矛盾”,对于本题即两个圆相交,则连一条边。对这个图求强连通分量,然后看是否有某对点属于同一个强连通分量。如果N对点每一对都属于不同的强连通分量,满足。否则不满足。然后二分半径即可。

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;typedef long long LL;const int MAXN=210;const int maxm=1010;const int MOD=1e9+7;const int INF=0x3f3f3f3f;const double EPS=1e-3;int n;  struct Edge{      int v,next;      Edge(){}      Edge(int _v,int _next):v(_v),next(_next){}  }edge[MAXN*MAXN];  int head[MAXN], size;  inline void initial(){      memset(head,-1,sizeof(int)*(n+2));      size = 0;  }  inline void add_edge(int u,int v){      edge[size] = Edge(v,head[u]);      head[u] = size ++;  }  int belong[MAXN];   bool vis[MAXN];  int depth;                   int bcnt;                    int dfn[MAXN], low[MAXN];    int stack[MAXN], tail ;  inline void Tarjan(int u){      dfn[u] = low[u] = depth ++;      vis[u] = 1;      stack[++tail] = u;      for(int i = head[u];i != -1;i = edge[i].next){          int v = edge[i].v;          if(dfn[v] == -1){              Tarjan(v);              if(low[u] > low[v])                  low[u] = low[v];          }else if(vis[v] && low[u] > dfn[v]){                  low[u] = dfn[v];          }      }      if(low[u] == dfn[u]){            bcnt ++;          int j;          do{              j = stack[tail--];              vis[j] = 0;              belong[j] = bcnt;          }while(j != u);      }  }  double x[MAXN], y[MAXN];  inline double Cal(int i,int j){      return (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]);  }  inline bool can(){      int N = n/2;      for(int i = 1;i <= N; ++i)          if(belong[i] == belong[i+N]) return false;      return true;  }  int main(){      int N;      while(scanf("%d",&N) != EOF){          n = 2*N;          for(int i = 1;i <= N; ++i)              scanf("%lf%lf%lf%lf",&x[i],&y[i],&x[i+N],&y[i+N]);          double right = 10000.0*10000.0, left = 0.0, mid;          while(right - left >= EPS){              mid = (right + left)/2.0;              initial();              for(int i = 1;i < n; ++i)                  for(int j = i + 1;j <= n; ++j){                      if(Cal(i,j) < mid){                          int u, v;                          if(i <= N) u = i + N;                          else u = i - N;                          if(j <= N) v = j + N;                          else v = j - N;                          add_edge(i,v);                          add_edge(j,u);                      }                  }              tail = depth = bcnt = 0;              memset(vis,0,sizeof(bool)*(n+2));              memset(dfn,-1,sizeof(int)*(n+2));              memset(low,0,sizeof(int)*(n+2));              for(int i = 1;i <= n; ++i)                  if(dfn[i] == -1) Tarjan(i);              if(can()) left = mid;              else right = mid;          }          printf("%.2lf\n",sqrt(left)/2.0);      }  }  

Examining the Rooms

Problem Description

A murder happened in the hotel. As the best detective in the town, you should examine all the N rooms of the hotel immediately. However, all the doors of the rooms are locked, and the keys are just locked in the rooms, what a trap! You know that there is exactly one key in each room, and all the possible distributions are of equal possibility. For example, if N = 3, there are 6 possible distributions, the possibility of each is 1/6. For convenience, we number the rooms from 1 to N, and the key for Room 1 is numbered Key 1, the key for Room 2 is Key 2, etc.
To examine all the rooms, you have to destroy some doors by force. But you don’t want to destroy too many, so you take the following strategy: At first, you have no keys in hand, so you randomly destroy a locked door, get into the room, examine it and fetch the key in it. Then maybe you can open another room with the new key, examine it and get the second key. Repeat this until you can’t open any new rooms. If there are still rooms un-examined, you have to randomly pick another unopened door to destroy by force, then repeat the procedure above, until all the rooms are examined.
Now you are only allowed to destroy at most K doors by force. What’s more, there lives a Very Important Person in Room 1. You are not allowed to destroy the doors of Room 1, that is, the only way to examine Room 1 is opening it with the corresponding key. You want to know what is the possibility of that you can examine all the rooms finally.

Input

The first line of the input contains an integer T (T ≤ 200), indicating the number of test cases. Then T cases follow. Each case contains a line with two numbers N and K. (1 < N ≤ 20, 1 ≤ K < N)

Output

Output one line for each case, indicating the corresponding possibility. Four digits after decimal point are preserved by rounding.

Sample Input

3
3 1
3 2
4 2

Sample Output

0.3333
0.6667
0.6250

Hint

Sample Explanation

When N = 3, there are 6 possible distributions of keys:

Room 1  Room 2  Room 3  Destroy Times

1 Key 1 Key 2 Key 3 Impossible #2 Key 1 Key 3 Key 2 Impossible #3 Key 2 Key 1 Key 3 Two #4 Key 3 Key 2 Key 1 Two #5 Key 2 Key 3 Key 1 One #6 Key 3 Key 1 Key 2 One

In the first two distributions, because Key 1 is locked in Room 1 itself and you can’t destroy Room 1, it is impossible to open Room 1.
In the third and forth distributions, you have to destroy Room 2 and 3 both. In the last two distributions, you only need to destroy one of Room 2 or Room

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;typedef long long LL;const int MAXN=25;const int MAXM=15;const LL INF=0x3f3f3f3f;int T,N,K;LL dp[MAXN][MAXN];int main(){    scanf("%d",&T);    while(T--){        scanf("%d%d",&N,&K);        LL fac=1;        for(int i=2;i<=N;i++) fac*=i;        memset(dp,0,sizeof(dp));        dp[0][0]=1;        for(int i=1;i<=N;i++)            for(int j=1;j<=i;j++){                dp[i][j]=dp[i-1][j]*(i-1)+dp[i-1][j-1];            }        LL ans=0,ans2=0;        for(int i=1;i<=K;i++) ans+=dp[N][i];        for(int i=1;i<=K-1;i++) ans2+=dp[N-1][i];        printf("%.4f\n",(double)(ans-ans2)/fac);    }    return 0;}

Shortest Path

Problem Description

When YY was a boy and LMY was a girl, they trained for NOI (National Olympiad in Informatics) in GD team. One day, GD team’s coach, Prof. GUO asked them to solve the following shortest-path problem.
There is a weighted directed multigraph G. And there are following two operations for the weighted directed multigraph:
(1) Mark a vertex in the graph.
(2) Find the shortest-path between two vertices only through marked vertices.
For it was the first time that LMY faced such a problem, she was very nervous. At this moment, YY decided to help LMY to analyze the shortest-path problem. With the help of YY, LMY solved the problem at once, admiring YY very much. Since then, when LMY meets problems, she always calls YY to analyze the problems for her. Of course, YY is very glad to help LMY. Finally, it is known to us all, YY and LMY become programming lovers.
Could you also solve the shortest-path problem?

Input

The input consists of multiple test cases. For each test case, the first line contains three integers N, M and Q, where N is the number of vertices in the given graph, N≤300; M is the number of arcs, M≤100000; and Q is the number of operations, Q ≤100000. All vertices are number as 0, 1, 2, … , N - 1, respectively. Initially all vertices are unmarked. Each of the next M lines describes an arc by three integers (x, y, c): initial vertex (x), terminal vertex (y), and the weight of the arc (c). (c > 0) Then each of the next Q lines describes an operation, where operation “0 x” represents that vertex x is marked, and operation “1 x y” finds the length of shortest-path between x and y only through marked vertices. There is a blank line between two consecutive test cases.
End of input is indicated by a line containing N = M = Q = 0.

Output

Start each test case with “Case #:” on a single line, where # is the case number starting from 1.
For operation “0 x”, if vertex x has been marked, output “ERROR! At point x”.
For operation “1 x y”, if vertex x or vertex y isn’t marked, output “ERROR! At path x to y”; if y isn’t reachable from x through marked vertices, output “No such path”; otherwise output the length of the shortest-path. The format is showed as sample output.
There is a blank line between two consecutive test cases.

Sample Input

5 10 10
1 2 6335
0 4 5725
3 3 6963
4 0 8146
1 2 9962
1 0 1943
2 1 2392
4 2 154
2 2 7422
1 3 9896
0 1
0 3
0 2
0 4
0 4
0 1
1 3 3
1 1 1
0 3
0 4
0 0 0

Sample Output

Case 1:
ERROR! At point 4
ERROR! At point 1
0
0
ERROR! At point 3
ERROR! At point 4

floyed变形

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;typedef long long LL;const int maxn=310;const int maxm=1010;const int MOD=1e9+7;const LL INF=1e18;int N,M,Q;LL f[maxn][maxn];int vis[maxn];LL dis[maxn][maxn];int main(){    int u,v,x,op;    int cas=1;    bool first=true;    while(scanf("%d%d%d",&N,&M,&Q)!=EOF,N+M+Q){        if(first)first=false;        else printf("\n");        memset(vis,0,sizeof(vis));        memset(dis,-1,sizeof(dis));        for(int i=0;i<=N;i++){            for(int j=0;j<=N;j++){                f[i][j]=INF;            }        }        for(int i=0;i<M;i++){            scanf("%d%d%d",&u,&v,&x);            if(dis[u][v]==-1)dis[u][v]=x;            else dis[u][v]=min(dis[u][v],1LL*x);        }        for(int i=0;i<=N;i++)dis[i][i]=0,f[i][i]=0;        printf("Case %d:\n",cas++);        while(Q--){            scanf("%d",&op);            if(op==0){                scanf("%d",&u);                if(vis[u])printf("ERROR! At point %d\n",u);                else {                    vis[u]=1;                    for(int i=0;i<N;i++){                        if(dis[i][u]==-1)continue;                        for(int j=0;j<N;j++){                            if(f[j][i]==INF)continue;                            f[j][u]=min(f[j][u],f[j][i]+dis[i][u]);                        }                    }                    for(int i=0;i<N;i++){                        if(f[i][u]==INF)continue;                        for(int j=0;j<N;j++){                            if(f[u][j]==INF)continue;                            f[i][j]=min(f[i][j],f[i][u]+f[u][j]);                        }                    }                }            } else {                scanf("%d%d",&u,&v);                if(!vis[u]||!vis[v]){                    printf("ERROR! At path %d to %d\n",u,v);                } else if(f[u][v]==INF){                    printf("No such path\n");                } else{                    printf("%I64d\n",f[u][v]);                }            }        }    }    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果7手机白屏黑苹果怎么办 衣服破了个洞怎么办 黑苹果自带升级怎么办 双显卡都禁用了怎么办 win10优盘识别不出来怎么办 黑苹果无限重启怎么办 水泥地面起砂怎么办?这几招很有用 跟老公没法过了怎么办 胃和肠子有点烂怎么办? 车的屏幕黑了怎么办 ios12玩游戏闪退怎么办 没网steam要登录怎么办 电脑有gta还需要安装怎么办 孤岛惊魂5卡顿怎么办 酷匠密码忘记了怎么办 战地1有时候卡死怎么办 战地一fps太低怎么办 Dnf与系统不兼容怎么办 使命召唤7显示w怎么办 战地3王者太卡怎么办 合金装备5消音器没了怎么办 红警基地没了怎么办 玩战地1帧数太低怎么办 战地1点游戏不开怎么办 ios耳机孔坏了怎么办? 吃泻药都不排便怎么办 上司离职了我该怎么办 我上司要辞职我怎么办 一方坚决不同意离婚我该怎么办 模拟农场车翻了怎么办 手机退出键坏了怎么办 dnf邮件发错了怎么办 手机提示sd卡已损坏怎么办 解压包文件数据损坏该怎么办 电脑被压缩后电脑打不开怎么办 眼睛里进了飞虫怎么办 虫子飞到眼睛里怎么办 云电脑pc版双鼠标怎么办 电脑蓝屏代码7f怎么办 笔记本电脑蓝屏开不了机怎么办 装xp系统后蓝屏怎么办