【网络流24题】星际转移(分层图+枚举)

传送门

    星际转移
    题意:给出若干容纳人数不同的太空船循环停站路线(特定时间停特定站),任意两站之间行驶耗时为1,求k个人从起点地球到终点月球的最小耗时.

I think

    分层图问题.对每个太空站i在第day天建立点< i,day>,相当于在枚举day时通过添加新边和新点将图层层展开.
    乘客可以在某个站点等待,因此需要增设< i,day-1> —> < i,day>容量为Inf的边.
    乘客可以坐车从站i到站j,因此需增设< i,day-1> —> < j,day>容量为车载量的边.
    当最大流==总人数k时day即答案.
    
    什么时候用分层图来解题? 从我的理解看,应当是在尝试用边的容量和费用设限然而仍然无法建出得到答案的图时,考虑用分层图枚举/二分答案.

Code

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

const int sm = 20*50+10;
const int sn = 1e6+10;
const int Inf = 0x3f3f3f3f;

int N,M,K,S,T,tot=1,Flw,d;
int to[sn],hd[sm],nxt[sn],_c[sn],c[sn];
int h[50],r[50],p[50][50],fa[50];
int lev[sm],cur[sm];

int Find(int x) {
    if(x!=fa[x]) return fa[x]=Find(fa[x]);
    return fa[x];
}
int Min(int x,int y) { return x<y?x:y; }
void Add(int u,int v,int w) {
    to[++tot]=v,nxt[tot]=hd[u],hd[u]=tot,_c[tot]=c[tot]=w;
    to[++tot]=u,nxt[tot]=hd[v],hd[v]=tot,_c[tot]=c[tot]=0;
}
bool Bfs(int sum) {
    for(int i=0;i<=sum;++i) 
        lev[i]=0; lev[T]=0;
    queue<int>q; int t;
    q.push(S),lev[S]=1;
    while(!q.empty()) {
        t=q.front(),q.pop();
        for(int i=hd[t];i;i=nxt[i])
            if(c[i]>0&&!lev[to[i]]) {
                lev[to[i]]=lev[t]+1;
                if(to[i]==T) return 1;
                q.push(to[i]);
            } 
    }
    return lev[T];
}
int Dfs(int x,int mx) {
    if(x==T||!mx) return mx;
    int f;
    for(int i=cur[x]?cur[x]:hd[x];i;i=nxt[i]) {
        cur[x]=i;
        if(c[i]>0&&lev[to[i]]==lev[x]+1) 
            if(f=Dfs(to[i],Min(mx,c[i])))
                return c[i]-=f,c[i^1]+=f,f;
    }
    return 0;
}
void Dinic(int sum) {
    int f; Flw=0;
    while(Bfs(sum)) {
        for(int i=0;i<=sum;++i) cur[i]=0; cur[T]=0;
        while(f=Dfs(S,Inf)) Flw+=f;
    }
}
int Point(int x,int d) {
    return d*N+x;
}
int main() {
    int u;
    scanf("%d%d%d",&N,&M,&K);
    for(int i=1;i<=N+2;++i) fa[i]=i;
    for(int i=1;i<=M;++i) {
        scanf("%d%d",&h[i],&r[i]);
        for(int j=1,v;j<=r[i];++j) {
            scanf("%d",&p[i][j]);
            if(!p[i][j]) p[i][j]=N+1;
            if(p[i][j]==-1) p[i][j]=N+2;
            u=Find(p[i][j]);
            if(j==1) v=u;
            else fa[u]=v;
        }
    }
    if(Find(N+1)!=Find(N+2)) puts("0");
    else {
        N+=2,S=0,T=sm-1;
        int q,fm,tt;
        Add(S,Point(N-1,0),Inf);
        Add(Point(N,0),T,Inf);
        do {
            ++d;
            if(d>1)
                for(int i=2;i<=tot;++i) c[i]=_c[i];
            Add(S,Point(N-1,d),Inf);
            Add(Point(N,d),T,Inf);
            for(int i=1;i<=N;++i) 
                Add(Point(i,d-1),Point(i,d),Inf);
            for(int i=1;i<=M;++i) {
                tt=d%r[i]+1;
                fm=(tt==1)?r[i]:tt-1;
                Add(Point(p[i][fm],d-1),Point(p[i][tt],d),h[i]);
            }
            Dinic((d+1)*N);
        }while(Flw<K);
        printf("%d\n",d);
    }
    return 0;
}
 子任务 #1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,我是一名自然语言处理模型,无法为您生成完整的代码。但我可以给您一些提示和建议。 对于一个星际争霸2赛事网站,您需要考虑以下几个方面: 1. 网站的功能需求:包括比赛日程表、比分、选手信息、比赛回放等等。 2. 网站的页面设计:需要考虑整体布局、色彩搭配、字体大小等等,可以使用Dreamweaver等工具进行页面设计。 3. 数据库设计:需要考虑如何存储赛事信息、选手信息、比分等数据,可以使用MySQL等数据库管理系统进行设计。 以下是一些可能有用的代码片段: 1. 连接MySQL数据库 ```php <?php $servername = "localhost"; $username = "username"; $password = "password"; // 创建连接 $conn = new mysqli($servername, $username, $password); // 检测连接 if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } echo "连接成功"; ?> ``` 2. 插入数据到MySQL数据库 ```php <?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "myDB"; // 创建连接 $conn = new mysqli($servername, $username, $password, $dbname); // 检测连接 if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } // 插入数据 $sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', 'john@example.com')"; if ($conn->query($sql) === TRUE) { echo "新记录插入成功"; } else { echo "Error: " . $sql . "<br>" . $conn->error; } $conn->close(); ?> ``` 3. 查询MySQL数据库中的数据 ```php <?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "myDB"; // 创建连接 $conn = new mysqli($servername, $username, $password, $dbname); // 检测连接 if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } // 查询数据 $sql = "SELECT id, firstname, lastname FROM MyGuests"; $result = $conn->query($sql); if ($result->num_rows > 0) { // 输出数据 while($row = $result->fetch_assoc()) { echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . $row["lastname"]. "<br>"; } } else { echo "0 结果"; } $conn->close(); ?> ``` 希望这些代码片段能对您有所帮助,但请注意,这只是一个简单的示例,实际的网站开发需要更加复杂和全面的考虑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值