小行星

整理一下最近做过的题。从后往前发好了。

星云中有n颗行星,每颗行星的位置是(x,y,z)。每次可以消除一个面(即x,y或z坐标相等)的行星,但是由于时间有限,求消除这些行星的最少次数。

突然发现自己不会最小割= =。考虑一下二维的情况,把坐标拆开,一对坐标连边跑最大流。
为什么是对的。代价->次数->割掉一条边。割边后的S集T集是都消除过的,所以最小割即为答案。

三维情况如上法把x,y,z相连发现y会重复使用,拆点限制流量。

#include<bits/stdc++.h>
using namespace std;

const int MAXN=3e5+5;
const int INF=1e9+7;

struct edge{
    int to,next,w;  
}e[MAXN<<2];

int n,m,s,t;
int cur[MAXN],head[MAXN],cnt=1;
inline void add(int u,int v,int w){
    e[++cnt]=(edge){v,head[u],w},head[u]=cnt;
    e[++cnt]=(edge){u,head[v],0},head[v]=cnt;
}

queue<int>q;
int dep[MAXN];
bool bfs(int x){
    memset(dep,0,sizeof(dep));
    q.push(x);dep[x]=1;
    while(q.size()){
        int u=q.front();q.pop();
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to,w=e[i].w;
            if(!dep[v]&&w){
                dep[v]=dep[u]+1;q.push(v);
            }
        }
    }
    if(!dep[t])return 0;
    return 1;
}

int dfs(int u,int flow){
    if(u==t||flow==0)return flow;
    for(int &i=cur[u];i;i=e[i].next){
        int v=e[i].to,w=e[i].w;
        if(dep[v]==dep[u]+1&&w){
            int tem=dfs(v,min(flow,w));
            if(tem){
                e[i].w-=tem;e[i^1].w+=tem;return tem;
            }
        }
    }
    return 0;
}

int dinic(){
    int ans=0;
    while(bfs(s)){
        for(int i=s;i<=t;i++)cur[i]=head[i];
        while(int d=dfs(s,INF))ans+=d;
    }
    return ans;
}

int jl[505],num=0;
bool vis1[505],vis2[505],vis3[505];

int main(){
    memset(vis1,0,sizeof(vis1));
    memset(vis2,0,sizeof(vis2));
    memset(vis3,0,sizeof(vis3));
    int x,y,z;
    scanf("%d",&n);
    s=0,t=2001+n;
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&x,&y,&z);
        if(!vis1[x])vis1[x]=1,add(s,x,1);
        if(!vis3[z])vis3[z]=1,add(1500+z,t,1);
        if(!vis2[y])vis2[y]=1,add(500+y,1000+y,1);
        add(x,500+y,1);add(1000+y,1500+z,1);
    }
    cout<<dinic();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Pygame库在Python中射击小行星的示例代码: ```python import pygame import random # 初始化Pygame pygame.init() # 设置游戏窗口的宽度和高度 screen_width = 800 screen_height = 600 # 创建游戏窗口 screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("射击小行星") # 加载玩家飞船图像 player_image = pygame.image.load("player_ship.png") player_rect = player_image.get_rect() player_rect.centerx = screen_width // 2 player_rect.bottom = screen_height - 10 # 加载小行星图像 asteroid_image = pygame.image.load("asteroid.png") # 创建玩家子弹的列表 bullets = [] # 设置游戏循环标志 running = True # 游戏主循环 while running: # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: # 创建子弹并添加到子弹列表中 bullet_rect = pygame.Rect(player_rect.centerx, player_rect.top, 5, 10) bullets.append(bullet_rect) # 移动玩家飞船 keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: player_rect.x -= 5 if keys[pygame.K_RIGHT]: player_rect.x += 5 # 移动子弹 for bullet in bullets: bullet.y -= 5 if bullet.y < 0: bullets.remove(bullet) # 绘制游戏场景 screen.fill((0, 0, 0)) screen.blit(player_image, player_rect) for bullet in bullets: pygame.draw.rect(screen, (255, 255, 255), bullet) pygame.display.flip() # 退出游戏 pygame.quit() ``` 请注意,上述代码仅为示例,您需要根据您的实际需求进行修改和完善。您还需要准备玩家飞船图像(player_ship.png)和小行星图像(asteroid.png)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值