要做这题,先要明白图的割,说白了就是 为了让原点无法到汇点要删几条边(之所以叫割,就是在图面上切一刀,减掉最小的边是原点和汇点成为两个集合),想到了割先放着一会用。

题中说只有沿最短路走才有可能追上,那么就意味着图中的最短路可能不止一条,沿着最短路走才能追上,那么其他的走法就没用了,所以只要求原点到汇点的最短路径图的最小割就可以知道最少断几条边可以堵住人了,再说第二问,既然最短路不止一条,那么只要边数量最小的一条最短路不被堵上,那个人就能追上炸弹张了,其他的边都可以赌上一点问题没有,这样就是总点数-最小最短路边数 等于第二问

写完交了几便都不对,逼的没招了去和题解,结果发现建图建错了!真是二逼的可以、、、、、、、、、、

   for(int i=;i<=n;i++)
{
for(int j=;j<g[i].size();j++)
{
edge e = g[i][j];
if(dis[e.to]-dis[i]==gg[i][e.to])
addedge(i,e.to,);
}

开始我是这么写的,后来我是这么写的

   for(int u = ; u <= n; u++) {
for(int i = ; i < g[u].size(); i++) {
int v = g[u][i].to, w = g[u][i].cap;
if(dis[u] + w == dis[v]) {
addedge(u, v, );
}
}
}

啥区别呢? 错的那个用了矩阵去访问边,但是点数和边数差那么多肯定是有重边的! 矩阵不能存重边!

AC代码,看见有人216ms ac   我就四百多、、、

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<queue>
#include<utility>
#define maxn 2001
#define inf 0xfffffff
using namespace std; typedef pair<int,int> P;
struct edge
{
int to,cap,rev;
};
vector<edge> group[maxn];
vector<edge> g[maxn];
int level[maxn],iter[maxn];
int dis[maxn],n,m,fro[maxn];
int vis[maxn],ans2;
int gg[maxn][maxn]; void dijkstra()
{
for(int i=;i<=n;i++)
{
dis[i]=inf;
}
dis[]=;
priority_queue<P,vector<P>, greater<P> > que;
que.push(P(,));
while(!que.empty())
{
P p=que.top();
que.pop();
int v=p.second;
if(dis[v]<p.first) continue;
for(int i=;i<g[v].size();i++)
{
edge e=g[v][i];
if(dis[e.to]>=dis[v]+e.cap)
{
dis[e.to]=dis[v]+e.cap;
que.push(P(dis[e.to],e.to));
}
}
}
}
void addedge(int from,int to,int cap)
{
group[from].push_back((edge){to,cap,group[to].size()});
group[to].push_back((edge){from,,group[from].size()-});
}
void build()
{
for(int u = ; u <= n; u++) {
for(int i = ; i < g[u].size(); i++) {
int v = g[u][i].to, w = g[u][i].cap;
if(dis[u] + w == dis[v]) {
addedge(u, v, );
}
}
}
/* for(int i=1;i<=n;i++)
{
for(int j=0;j<g[i].size();j++)
{
edge e = g[i][j];
if(dis[e.to]-dis[i]==gg[i][e.to])
addedge(i,e.to,1);
}
}*/
}
void bfs(int s)
{
memset(level,-,sizeof(level));
queue<int> que;
level[s] = ;
que.push(s);
while(!que.empty())
{
int v=que.front();
que.pop();
for(int i=;i<group[v].size();i++)
{
edge &e=group[v][i];
if(e.cap>&&level[e.to]<)
{
level[e.to]=level[v]+;
que.push(e.to);
}
}
}
}
int dfs(int v,int t,int f)
{
if(v == t) return f;
for(int &i=iter[v];i<group[v].size();i++)
{
edge &e=group[v][i];
if(e.cap>&&level[v]<level[e.to])
{
int d=dfs(e.to,t,min(f,e.cap));
if(d>)
{
e.cap -= d;
group[e.to][e.rev].cap +=d;
return d;
}
}
}
return ;
}
int max_flow(int s,int t)
{
int flow=;
while(true)
{
bfs(s);
if(level[t]<) return flow;
memset(iter,,sizeof(iter));
int f;
while((f=dfs(s,t,inf))>)
{
flow+=f;
}
}
}
int minedge()
{
for(int k=;k<=n;k++)
fro[k]=inf;
fro[]=;
queue<int> Q;
Q.push();
while(!Q.empty())
{
int s=Q.front();
Q.pop();
if(s==n) break;
for(int i=;i<g[s].size();i++)
{
edge e=g[s][i];
if(dis[s]+e.cap==dis[e.to])
{
if(fro[s]+<fro[e.to])
{
fro[e.to]=fro[s]+;
Q.push(e.to);
}
}
}
}
return fro[n];
}
int main()
{
// freopen("1007.in", "r", stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=;i<=n;i++)
g[i].clear();
memset(gg,,sizeof(gg));
for(int i=;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a].push_back((edge){b,c,});
g[b].push_back((edge){a,c,});
gg[a][b]=c;
gg[b][a]=c;
}
for(int i=;i<=maxn;i++)
group[i].clear();
dijkstra();
ans2=minedge();
build();
int ans1 = max_flow(,n);
printf("%d %d\n",ans1,m-ans2);
}
return ;
}

15年多校第一场七题hdu5294的更多相关文章

  1. 2019年牛客多校第一场B题Integration 数学

    2019年牛客多校第一场B题 Integration 题意 给出一个公式,求值 思路 明显的化简公式题,公式是分母连乘形式,这个时候要想到拆分,那如何拆分母呢,自然是裂项,此时有很多项裂项,我们不妨从 ...

  2. 【2019多校第一场补题 / HDU6578】2019多校第一场A题1001Blank——dp

    HDU6578链接 题意 有一串字符串,仅由 {0,1,2,3}\{0, 1, 2, 3\}{0,1,2,3} 组成,长度为 nnn,同时满足 mmm 个条件.每个条件由三个整数组成:l.r.xl.r ...

  3. 2014多校第一场 E 题 || HDU 4865 Peter's Hobby (DP)

    题目链接 题意 : 给你两个表格,第一个表格是三种天气下出现四种湿度的可能性.第二个表格是,昨天出现的三种天气下,今天出现三种天气的可能性.然后给你这几天的湿度,告诉你第一天出现三种天气的可能性,让你 ...

  4. 2014多校第一场J题 || HDU 4870 Rating(DP || 高斯消元)

    题目链接 题意 :小女孩注册了两个比赛的帐号,初始分值都为0,每做一次比赛如果排名在前两百名,rating涨50,否则降100,告诉你她每次比赛在前两百名的概率p,如果她每次做题都用两个账号中分数低的 ...

  5. 2014多校第一场A题 || HDU 4861 Couple doubi

    题目链接 题意 : 有K个球,给你一个数P,可以求出K个值,(i=1,2,...,k) : 1^i+2^i+...+(p-1)^i (mod p).然后女朋友先取,再xp取,都希望赢,如果女朋友能赢输 ...

  6. Card Hand Sorting 18中南多校第一场C题

    一.题意 随机给你一堆牌(标准扑克牌),之后让你按照: 第一优先规则:所有相同花色的在一起 第二优先规则:所有相同花色的必须按照升序或者降序排列 问,你最少要拿出多少张牌插入到其他的地方以维持这个状况 ...

  7. 【2019多校第一场补题 / HDU6582】2019多校第一场E题1005Path——最短路径+网络流

    HDU6582链接 题意 在一张有向图中,有一个起点和一个终点,你需要删去部分路径,使得起点到终点的最短距离增加(并不要求需要使得距离变成最大值),且删除的路径长度最短.求删去的路径总长为多少 分析 ...

  8. 2014多校第一场 I 题 || HDU 4869 Turn the pokers(费马小定理+快速幂模)

    题目链接 题意 : m张牌,可以翻n次,每次翻xi张牌,问最后能得到多少种形态. 思路 :0定义为反面,1定义为正面,(一开始都是反), 对于每次翻牌操作,我们定义两个边界lb,rb,代表每次中1最少 ...

  9. 2014多校第一场D题 || HDU 4864 Task (贪心)

    题目链接 题意 : 用N台机器,M个任务,每台机器都有一个最大工作时间和等级,每个任务有一个需要工作时间和一个等级.如果机器完成一个任务要求是:机器的工作时间要大于等于任务的时间,机器的等级要大于等于 ...

随机推荐

  1. vue.js数据绑定语法

    原始高清大图下载 1.数据绑定 html代码: <div id="first" class="first">msg:{{msg}}</div& ...

  2. EF批量插入数据耗时对比

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. Java 面向对象,封装,继承

    1相关概念的理解 1.1面向过程.面向对象 面向过程与面向对象都是编程中,编写程序的一种思维方式. 面向过程的程序设计方式,是遇到一件事时,思考“我该怎么做”,然后一步步实现的过程.(职员思想) 面向 ...

  4. 测试的发现遗漏BUG的做法

    首先要确认BUG的影响范围: 后续做法如下: 1.从测试角度来说,外部缺陷等同与系统崩溃,测试是必须提的2.可以询问主管或负责人是否在后一个版本中修改3.评估缺陷对于用户使用存在多大的不便4.判定缺陷 ...

  5. HTTP1.0工作原理

    1.HTTP工作原理 <HTTP响应报文与工作原理详解>讲的比较详细了. 2.示例 (1)server端程序如下: package org.yeyouluo.demo.jsp; impor ...

  6. C++string类型转换为C数组

    #include <string> #include <iostream> using namespace std; int main(){ string str; str.a ...

  7. 地址栏传值 JS取值方法

    function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...

  8. jsp跳转标签<jsp:forward>

    forward.jsp <%@ page language="java" contentType="text/html; charset=utf-8" p ...

  9. Java 继承与重写

    1.类的继承 1)继承 父类:所有子类所共有的属性和行为 子类:子类所特有的属性和行为 通过extends关键字来实现类的继承 子类(Sub class)可以继承父类(Super class)的成员变 ...

  10. 2017.10.1 QBXT 模拟赛

    题目链接 T1 枚举右端点,前缀和优化.对于当前点x,答案为 sum[x][r]-sum[x][l-1]-(sum[z][r]-sum[z][l-1]) 整理为 sum[x][r]-sum[z][r] ...