考虑“删除后图仍连通”,即其不是无向图的桥(bridge),可以用Tarjan算法预处理,这里不赘述。

【算法一】

枚举删除的是哪条边,然后枚举起点,暴搜,统计答案。

可以通过0、1号测试点。

预计得分:20分。

【算法二】

枚举删除的是哪条边,接着,

①枚举起点,∵op=0,∴裸最短路,Heap-dijkstra/SPFA。时间复杂度: O(m2*n*logn)/O(m2*n*k)。

②Floyd,时间复杂度O(m*n3)。

可以通过0、1、2、3号测试点。

预计得分:40分。

【算法三】

枚举删的是哪条边,接着,枚举终点,逆着推回去,考虑op=1的边,则有w[U][V]=(dis[U]+18)/19。然后跑Heap-dijkstra/SPFA即可。

时间复杂度:O(m2*n*logn)/O(m2*n*k)。

可以通过0、1、2、3、4、5号测试点。

预计得分:60分。

【算法四】

考虑删除某条边E后,以某个点U为终点的最短路是否发生变化。

我们发现,在某个无向图中,以U为根节点,到其他所有点的最短路构成了一棵树,即“最短路树(shortest-path tree)”。我们删除的边如果不在最短路树上,对当前图中的以U为起点的所有最短路不发生变化。

我们可以在Heap-dijkstra/SPFA的同时处理出最短路树:

if(dis[V]>dis[U]+w[U][V]) TreeEdge[S][V]=Edge[U][V];

//TreeEdge[S][V]表示以S为起点的单源最短路树中,V结点的父边。

于是算法得出:

首先枚举终点,然后枚举删除的边,仅仅需要重复求删除n-1条在最短路树上的边的答案即可,其他的边可以直接用之前预处理的答案就好了。

时间复杂度:O(n2*m*logn)/O(n2*k*m)。Heap-dijkstra可能需要卡常数。

预计得分:100分。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define N 111
#define M 1101
queue<int>q;
int dis[N],ans,ans2[M<<1],sumv[N],need[N];
int n,m,first[N],next[M<<1],v[M<<1],en,TEs[N][N]/*树边*/,x,y,es[N][N];
bool w[M<<1]/*道路类型*/,z,Del[M<<1]/*当前删除的边*/,ontree[N][M<<1]
/*ontree[i][j]表示边j是否在以i为汇点的最短路树上*/,inq[N];
void AddEdge(const int &U,const int &V,const bool &W)
{
v[en]=V; w[en]=W;
next[en]=first[U];
first[U]=en;
es[U][V]=en++;
}
int calc(const int &U,const bool &op){return op ? (dis[U]+18)/19 : 1;}
void spfa(const int &s,const bool &op)
{
memset(dis,0x7f,sizeof(dis));
memset(inq,0,sizeof(inq));
dis[s]=need[s]; inq[s]=1; q.push(s);
while(!q.empty())
{
int U=q.front();
for(int i=first[U];i!=-1;i=next[i]) if(!Del[i])
{
int C=calc(U,w[i]);
if(dis[v[i]]>dis[U]+C)
{
if(!op) TEs[s][v[i]]=es[U][v[i]];
dis[v[i]]=dis[U]+C;
if(!inq[v[i]])
q.push(v[i]),inq[v[i]]=1;
}
}
q.pop(); inq[U]=0;
}
if(!op)
{
for(int i=1;i<=n;++i)
sumv[s]+=dis[i];
ans+=sumv[s];
for(int i=1;i<=n;++i)
if(i!=s)
ontree[s][TEs[s][i]]=ontree[s][TEs[s][i]^1]=1;
}
}
int dfn[N],dep;
bool bridge[M<<1];
int Tarjan(int U,int fa)
{
int lowU=dfn[U]=++dep;
for(int i=first[U];i!=-1;i=next[i])
if(!dfn[v[i]])
{
int lowV=Tarjan(v[i],U);
lowU=min(lowU,lowV);
if(lowV>dfn[U])
bridge[i]=bridge[i^1]=1;
}
else if(v[i]!=fa)
lowU=min(lowU,dfn[v[i]]);
return lowU;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&need[i]);
memset(first,-1,sizeof(first));
for(int i=1;i<=m;++i)
{
scanf("%d%d%d",&x,&y,&z);
AddEdge(x,y,z);
AddEdge(y,x,z);
}
Tarjan(1,0);
for(int i=1;i<=n;++i)
spfa(i,0);
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
if((!bridge[TEs[i][j]])&&(j!=i))
{
Del[TEs[i][j]]=Del[TEs[i][j]^1]=1;
spfa(i,1);
Del[TEs[i][j]]=Del[TEs[i][j]^1]=0;
int tmp=ans2[TEs[i][j]];
for(int k=1;k<=n;++k)
ans2[TEs[i][j]]+=dis[k];
ans2[TEs[i][j]^1]+=(ans2[TEs[i][j]]-tmp);
}
for(int j=0;j<en;++j)
if((!bridge[j])&&(!ontree[i][j]))
ans2[j]+=sumv[i];
}
printf("%d %d\n",ans,*max_element(ans2,ans2+en));
return 0;
}

【spfa】bzoj3921 Mimori与树海的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. 【BZOJ-3627】路径规划 分层图 + Dijkstra + spfa

    3627: [JLOI2014]路径规划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 186  Solved: 70[Submit][Status] ...

  3. POJ 2387 Til the Cows Come Home(最短路 Dijkstra/spfa)

    传送门 Til the Cows Come Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 46727   Acce ...

  4. sgu 240 Runaway (spfa)

    题意:N点M边的无向图,边上有线性不下降的温度,给固定入口S,有E个出口.逃出去,使最大承受温度最小.输出该温度,若该温度超过H,输出-1. 羞涩的题意 显然N*H的复杂度dp[n][h]表示到达n最 ...

  5. spfa模板

    通过stl的queue实现的spfa(vector实现邻接表存图) 本模板没有考虑存在两点不连通的情况 如果需要判断则需要用到并查集或者遍历整个邻接表 #include<iostream> ...

  6. SPFA

    SPFA算法用来求单源最短路.可以处理任何有解的情况. 先建一个数组\(dist_x = 起点到x的最短路长度\),当\(x=起点\)时为0,当x和起点不通时为INF(本题中为\(2^31-1\)). ...

  7. BZOJ2763 [JLOI2011]飞行路线(SPFA + DP)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=2763 Description Alice和Bob现在要乘飞机旅行,他们选择了一家 ...

  8. bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)

    数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...

  9. bzoj 1179[Apio2009]Atm (tarjan+spfa)

    题目 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一 ...

随机推荐

  1. Educational Codeforces Round 55:B. Vova and Trophies

    B. Vova and Trophies 题目链接:https://codeforc.es/contest/1082/problem/B 题意: 给出一个“GS”串,有一次交换两个字母的机会,问最大的 ...

  2. handler更新ui线程的基本用法

    1.因为费时操作要放子线程,更新UI要放UI线程(主线程),所以子线程和主线程通信,通信的话要用到handler这个东西. 这里讲的比较简单,举2个例子说明 2.使用post的是handler ,使用 ...

  3. Java之戳中痛点 - (1)易变业务使用脚本语言编写

    脚本语言的3大特征: 1.灵活:脚本语言一般是动态类型,可以不声明变量类型直接使用,也可以在运行期改变类型:2.便捷:脚本语言是解释性语言,在运行期变更非常方便,而不用重启服务3.简单:脚本语言语法比 ...

  4. 【转载】How long is “too long” for MySQL Connections to sleep?

    From:http://dba.stackexchange.com/questions/1558/how-long-is-too-long-for-mysql-connections-to-sleep ...

  5. 【UVALive4685-Succession】树形DP

    http://acm.hust.edu.cn/vjudge/problem/14338 题意:给定一棵树,每个点有一个值,让你选择k个点,并且这k个点是连在一起的(从任意一个点出发,可以遍历完所有选择 ...

  6. OOP第三次上机

    上机问题 T1 CSet 还是熟悉的CSet,只是多了个构造函数以及收缩空间. T2 SingleTon 单例问题. 用一个指针保存唯一的实例,用户无法在外部直接新建实例,只能使用外部接口(函数),函 ...

  7. PHP中HTTP_X_FORWARDED_FOR、REMOTE_ADDR和HTTP_CLIENT_IP

    1.REMOTE_ADDR:浏览当前页面的用户计算机的ip地址 2.HTTP_X_FORWARDED_FOR: 浏览当前页面的用户计算机的网关 3.HTTP_CLIENT_IP:客户端的ip 在PHP ...

  8. javascript中实例方法与类方法的区别

    在javascript中,类有静态属性和实例属性之分,也有静态方法和实例方法之分 类属性(静态属性):通过类直接访问,不需要声明类的实例来访问 类方法(静态方法):通过类直接访问,不需要声明类的实例来 ...

  9. LeetCode 4 :Majority Element

    problem:Given an array of size n, find the majority element. The majority element is the element tha ...

  10. Kuangbin 带你飞 最小生成树题解

    整套题都没什么难度. POJ 1251 Jungle Roads #include <map> #include <set> #include <list> #in ...