• loj 1154(最大流+枚举汇点)


    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26868

    思路:拆点,容量为最多能跳的步数,然后设立一个超级源点,源点与各点两连边,容量为一开始的企鹅数,最后就是枚举汇点了,跑最大流验证即可。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cmath>
      7 using namespace std;
      8 #define MAXN 222
      9 #define MAXM 222222
     10 #define inf 1<<30
     11 #define FILL(a,b) memset(a,b,sizeof(a))
     12 
     13 struct Edge{
     14     int v,cap,next;
     15 }edge[MAXM];
     16 
     17 int n,vs,vt,NV,NE,head[MAXN];
     18 double d;
     19 
     20 
     21 void Insert(int u,int v,int cap)
     22 {
     23     edge[NE].v=v;
     24     edge[NE].cap=cap;
     25     edge[NE].next=head[u];
     26     head[u]=NE++;
     27 
     28     edge[NE].v=u;
     29     edge[NE].cap=0;
     30     edge[NE].next=head[v];
     31     head[v]=NE++;
     32 }
     33 
     34 int level[MAXN],gap[MAXN];
     35 void bfs(int vt)
     36 {
     37     FILL(level,-1);
     38     FILL(gap,0);
     39     queue<int>que;
     40     que.push(vt);
     41     level[vt]=0;
     42     gap[0]++;
     43     while(!que.empty()){
     44         int u=que.front();
     45         que.pop();
     46         for(int i=head[u];i!=-1;i=edge[i].next){
     47             int v=edge[i].v;
     48             if(level[v]!=-1)continue;
     49             level[v]=level[u]+1;
     50             gap[level[v]]++;
     51             que.push(v);
     52         }
     53     }
     54 }
     55 
     56 int pre[MAXN],cur[MAXN];
     57 int SAP(int vs,int vt)
     58 {
     59     bfs(vt);
     60     memcpy(cur,head,sizeof(head));
     61     int u=pre[vs]=vs,aug=inf,maxflow=0;
     62     gap[0]=NV;
     63     while(level[vs]<NV){
     64         bool flag=false;
     65         for(int &i=cur[u];i!=-1;i=edge[i].next){
     66             int v=edge[i].v;
     67             if(edge[i].cap>0&&level[u]==level[v]+1){
     68                 flag=true;
     69                 aug=min(aug,edge[i].cap);
     70                 pre[v]=u;
     71                 u=v;
     72                 if(v==vt){
     73                     maxflow+=aug;
     74                     for(u=pre[u];v!=vs;v=u,u=pre[u]){
     75                         edge[cur[u]].cap-=aug;
     76                         edge[cur[u]^1].cap+=aug;
     77                     }
     78                     aug=inf;
     79                 }
     80                 break;
     81             }
     82         }
     83         if(flag)continue;
     84         int minlevel=NV;
     85         for(int i=head[u];i!=-1;i=edge[i].next){
     86             int v=edge[i].v;
     87             if(edge[i].cap>0&&level[v]<minlevel){
     88                 cur[u]=i;
     89                 minlevel=level[v];
     90             }
     91         }
     92         if(--gap[level[u]]==0)break;
     93         level[u]=minlevel+1;
     94         gap[level[u]]++;
     95         u=pre[u];
     96     }
     97     return maxflow;
     98 }
     99 
    100 struct Node{
    101     double x,y;
    102     int num,step;
    103 }node[MAXN];
    104 
    105 double Get_Dist(int i,int j)
    106 {
    107     double d1=(node[i].x-node[j].x)*(node[i].x-node[j].x);
    108     double d2=(node[i].y-node[j].y)*(node[i].y-node[j].y);
    109     return sqrt(d1+d2);
    110 }
    111 
    112 void Build(int ed)
    113 {
    114     NE=0;
    115     FILL(head,-1);
    116     vs=0,vt=2*n+1;
    117     NV=vt+1;
    118     for(int i=1;i<=n;i++){
    119         Insert(i,i+n,node[i].step);
    120         Insert(vs,i,node[i].num);
    121     }
    122     for(int i=1;i<=n;i++){
    123         for(int j=i+1;j<=n;j++){
    124             if(Get_Dist(i,j)<=d){
    125                 Insert(i+n,j,inf);
    126                 Insert(j+n,i,inf);
    127             }
    128         }
    129     }
    130     Insert(ed,vt,inf);
    131 }
    132 
    133 int main()
    134 {
    135     int _case,ans,sum,flag,t=1;
    136     scanf("%d",&_case);
    137     while(_case--){
    138         scanf("%d%lf",&n,&d);
    139         sum=0;
    140         for(int i=1;i<=n;i++){
    141             scanf("%lf%lf%d%d",&node[i].x,&node[i].y,&node[i].num,&node[i].step);
    142             sum+=node[i].num;
    143         }
    144         flag=0;
    145         printf("Case %d:",t++);
    146         //枚举集中点
    147         for(int i=1;i<=n;i++){
    148             Build(i);
    149             if(SAP(vs,vt)==sum)flag=1,printf(" %d",i-1);
    150         }
    151         if(!flag)printf(" -1");
    152         puts("");
    153     }
    154     return 0;
    155 }
    View Code
  • 相关阅读:
    Spring Richclient — 企业级富客户端开发框架介绍,第 1 部分
    oracle的表名、字段名、constraint名的长度限制分别是多少?
    eclipse指定启动的jdk
    女人为什么爱攀比?
    Oracle一些常用的查询命令总结(持续更新)
    js冒泡事件之之之
    Aspose插件
    oracle11g导入到10g
    转:OpenCms 9.0.1汉化
    metasploit常用命令
  • 原文地址:https://www.cnblogs.com/wally/p/3351640.html
Copyright © 2020-2023  润新知