2014 Super Training #10 C Shadow --SPFA/随便搞/DFS
原题: FZU 2169 http://acm.fzu.edu.cn/problem.php?pid=2169
这题貌似有两种解法,DFS和SPFA,但是DFS怎么都RE,SPFA也要用邻接表表示边,用向量表示的话会TLE,而且用SPFA有一个异或,就是题目说要沿最短路走到都城,但是SPFA是走最短路去消灭叛军,然后再走回都城,我不知道怎么回事,不知道能不能有大神解释。因为这样的话,有多少叛军就能消灭多少叛军了,那就不要用什么算法 了,直接一个统计。于是试了一下,居然A了,瞬间变成大水题,我无法再评价这个题目了,就当消遣了。
SPFA法:依次从每个军队城市出发做一次SPFA,看到有能到的(肯定能到啊)叛军就将其消灭。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#define Mod 1000000007
using namespace std;
#define N 100007 struct Edge
{
int v,next;
}G[*N];
int head[N],tot;
int army[N],rebel[N];
int vis[N],dis[N];
int res;
int n,m; void addedge(int u,int v)
{
G[tot].v = v;
G[tot].next = head[u];
head[u] = tot++;
} void SPFA(int s)
{
int i;
memset(vis,,sizeof(vis));
queue<int> que;
while(!que.empty())
que.pop();
que.push(s);
vis[s] = ;
dis[s] = ;
while(!que.empty())
{
int tmp = que.front();
que.pop();
vis[tmp] = ;
for(i=head[tmp];i!=-;i=G[i].next)
{
int v = G[i].v;
if(dis[v] > dis[tmp] + )
{
dis[v] = dis[tmp]+;
if(!vis[v])
{
que.push(v);
vis[v] = ;
}
}
}
}
} int main()
{
int i,j,x;
int u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(army,,sizeof(army));
memset(rebel,,sizeof(rebel));
memset(head,-,sizeof(head));
tot = ;
int cnt = ;
for(i=;i<=n;i++)
{
scanf("%d",&rebel[i]);
if(rebel[i])
cnt++;
}
for(i=;i<=m;i++)
scanf("%d",&army[i]);
for(i=;i<n-;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
res = ;
for(i=;i<=m;i++)
{
SPFA(army[i]);
for(j=;j<=n;j++)
{
if(dis[j] != Mod)
{
if(rebel[j])
{
res += rebel[j];
rebel[j] = ;
cnt--;
}
}
}
if(cnt == ) //已经消灭完
break;
}
printf("%d\n",res);
}
return ;
}
DFS法(选GNU C++ 会Runtime Error,要选Visual C++):
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#define Mod 1000000007
#define ll long long
using namespace std;
#define N 100007 struct Edge
{
int v,next;
}G[*N];
int head[N],tot;
int army[N],rebel[N];
ll sum;
int n,m; void addedge(int u,int v)
{
G[tot].v = v;
G[tot].next = head[u];
head[u] = tot++;
} int dfs(int u,int val,int fa)
{
int soni = ;
if(army[u]) //找到军队
{
sum += val;
soni++;
}
for(int i=head[u];i!=-;i=G[i].next)
{
int v = G[i].v;
if(v == fa)
continue;
soni += dfs(v,val+rebel[u],u);
}
if(soni > )
sum -= (soni-)*rebel[u];
return soni;
} int main()
{
int i,j,x;
int u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(army,,sizeof(army));
memset(rebel,,sizeof(rebel));
memset(head,-,sizeof(head));
tot = ;
for(i=;i<=n;i++)
scanf("%d",&rebel[i]);
for(i=;i<=m;i++)
{
scanf("%d",&x);
army[x] = ;
}
for(i=;i<n-;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
sum = ;
dfs(,,-);
printf("%lld\n",sum);
}
return ;
}
直接统计:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
#define N 100007 int army[N],rebel[N];
int res;
int n,m; int main()
{
int i,j,x;
int u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(rebel,,sizeof(rebel));
int cnt = ;
res = ;
for(i=;i<=n;i++)
{
scanf("%d",&rebel[i]);
if(rebel[i])
res += rebel[i];
}
for(i=;i<=m;i++)
scanf("%d",&army[i]);
for(i=;i<n-;i++)
scanf("%d%d",&u,&v);
if(m == )
{
puts("");
continue;
}
printf("%d\n",res);
}
return ;
}
2014 Super Training #10 C Shadow --SPFA/随便搞/DFS的更多相关文章
- 2014 Super Training #10 G Nostop --矩阵快速幂
原题: FZU 2173 http://acm.fzu.edu.cn/problem.php?pid=2173 一开始看到这个题毫无头绪,根本没想到是矩阵快速幂,其实看见k那么大,就应该想到用快速幂什 ...
- 2014 Super Training #10 D 花生的序列 --DP
原题: FZU 2170 http://acm.fzu.edu.cn/problem.php?pid=2170 这题确实是当时没读懂题目,连样例都没想通,所以没做了,所以还是感觉这样散漫的做不好,有些 ...
- 2014 Super Training #9 F A Simple Tree Problem --DFS+线段树
原题: ZOJ 3686 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686 这题本来是一个比较水的线段树,结果一个ma ...
- 2014 Super Training #7 C Diablo III --背包问题(DP)
原题: ZOJ 3769 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769 一个带有一些限制的背包问题. 假设在没有限 ...
- 2014 Super Training #6 B Launching the Spacecraft --差分约束
原题:ZOJ 3668 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3668 典型差分约束题. 将sum[0] ~ sum ...
- 2014 Super Training #4 E Paint the Grid Reloaded --联通块缩点+BFS
原题: ZOJ 3781 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 题意: 给一个n*m的X,O构成的格子,对 ...
- 2014 Super Training #3 H Tmutarakan Exams --容斥原理
原题: URAL 1091 http://acm.timus.ru/problem.aspx?space=1&num=1091 题意:要求找出K个不同的数字使他们有一个大于1的公约数,且所有 ...
- 2014 Super Training #8 B Consecutive Blocks --排序+贪心
当时不知道怎么下手,后来一看原来就是排个序然后乱搞就行了. 解法不想写了,可见:http://blog.csdn.net/u013368721/article/details/28071241 其实就 ...
- 2014 Super Training #8 A Gears --并查集
题意: 有N个齿轮,三种操作1.操作L x y:把齿轮x,y链接,若x,y已经属于某个齿轮组中,则这两组也会合并.2.操作Q x y:询问x,y旋转方向是否相同(等价于齿轮x,y的相对距离的奇偶性). ...
随机推荐
- CentOS7 Debian 8 安装VMware-tools
如在安装过程中碰到未找到gcc 或者 kernel headers的可按以下方案解决,适用任意版本 CentOS 7 1. Update the kernel: $ yum update kernel ...
- C#6.0语法糖剖析(一)
1.自动属性默认初始化 使用代码 "; 编译器生成的代码: public class Customer { [CompilerGenerated] private string kBacki ...
- Sharepoint学习笔记—习题系列--70-573习题解析 -(Q40-Q44)
Question 40You need to send a single value from a consumer Web Part to a provider Web Part.Which int ...
- IO流-输入输出
java的I/O技术可以将数据保存到文本.二进制.ZIP压缩文件中,下面来说说一些基本的常识(今天只讲理论).先来说说流,何为流?“流就是一组有序的数据序列,根据操作的类型,可以分为输入(Input) ...
- Visual Studio发布Web项目报错:Unable to add 'xxx' to the Web site. Unable to add file 'xxx'. The specified file could not be encrypted.
背景 Visual Studio下的Web项目 现象 发布时遇到Unable to add 'xxx' to the Web site. Unable to add file 'xxx'. The ...
- 在js中获取get参数(仿PHP)
复制粘贴即可..然后就可以在js中像PHP用$_GET['name']这样子获取get参数了!! /*--------------------(返回 $_GET 对象, 仿PHP模式)-------- ...
- 编写一个Java程序,计算半径为3.0的圆周长和面积并输出结果。把圆周率π定义为常量,半径定义为变量,然后进行计算并输出结果。
- PL/SQL之--触发器
一.简介 触发器在数据库里以独立的对象进行存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来触发运行.oracle事件指的是对数据库的表或视图进行的inse ...
- android适配器及监听点击和滚动在ListView中的使用
package com.example.demon08; import java.util.ArrayList;import java.util.HashMap;import java.util.Li ...
- Github学习之路-小试牛刀,练习Git 的基本操作
一.下子windows客户端. Git 客户端下载地址:http://msysgit.github.io/ 二.打开Git Bash 命令行操作界面. 安装完成后,在开始菜单里找到“Git”-> ...