原题: 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的更多相关文章

  1. 2014 Super Training #10 G Nostop --矩阵快速幂

    原题: FZU 2173 http://acm.fzu.edu.cn/problem.php?pid=2173 一开始看到这个题毫无头绪,根本没想到是矩阵快速幂,其实看见k那么大,就应该想到用快速幂什 ...

  2. 2014 Super Training #10 D 花生的序列 --DP

    原题: FZU 2170 http://acm.fzu.edu.cn/problem.php?pid=2170 这题确实是当时没读懂题目,连样例都没想通,所以没做了,所以还是感觉这样散漫的做不好,有些 ...

  3. 2014 Super Training #9 F A Simple Tree Problem --DFS+线段树

    原题: ZOJ 3686 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686 这题本来是一个比较水的线段树,结果一个ma ...

  4. 2014 Super Training #7 C Diablo III --背包问题(DP)

    原题: ZOJ 3769 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769 一个带有一些限制的背包问题. 假设在没有限 ...

  5. 2014 Super Training #6 B Launching the Spacecraft --差分约束

    原题:ZOJ 3668 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3668 典型差分约束题. 将sum[0] ~ sum ...

  6. 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构成的格子,对 ...

  7. 2014 Super Training #3 H Tmutarakan Exams --容斥原理

    原题: URAL 1091  http://acm.timus.ru/problem.aspx?space=1&num=1091 题意:要求找出K个不同的数字使他们有一个大于1的公约数,且所有 ...

  8. 2014 Super Training #8 B Consecutive Blocks --排序+贪心

    当时不知道怎么下手,后来一看原来就是排个序然后乱搞就行了. 解法不想写了,可见:http://blog.csdn.net/u013368721/article/details/28071241 其实就 ...

  9. 2014 Super Training #8 A Gears --并查集

    题意: 有N个齿轮,三种操作1.操作L x y:把齿轮x,y链接,若x,y已经属于某个齿轮组中,则这两组也会合并.2.操作Q x y:询问x,y旋转方向是否相同(等价于齿轮x,y的相对距离的奇偶性). ...

随机推荐

  1. Ajax基础实例

    前端代码 <script type="text/javascript"> var xmlhttp; function go(url) { xmlhttp=null; i ...

  2. C# 线程同步

    Mutex 类 使用Mutex类来同步两个单独的程序.Mutex是一种原始的同步方式,其只对一个线程授予对共享资源的独占访问. const string NutexName = "C&quo ...

  3. sublime text 3 安装

    sublime text 3 下载地址 http://www.sublimetext.com/3 下载windows版本,然后解压缩就可以直接使用了,不错不错哦, 为了更加便捷的管理,安装 packa ...

  4. IOS客户端Coding项目记录(五)

    1:统一修改导航栏的样式,在 AppDelegate.m中 - (BOOL)application:(UIApplication *)application didFinishLaunchingWit ...

  5. android拍照选择图片上传服务器自定义控件

    做android项目的时候总免不了遇到图片上传功能,虽然就是调用android系统的拍照和相册选择功能,但是总面部了把一大推代码写在activity里,看上去一大推代码头都昏了.不如把这些功能都集成一 ...

  6. JSONKit解析json数据

    先将第三方文件拖进工程 JSONKit.h和JSONKit.m 然后设置在ARC工程中添加MRC文件,如下图所示 #import "ViewController.h" #impor ...

  7. 【转】XCode: duplicate symbol 解决方案

    遇到引用库重复定义的问题,需要解决. 项目需要,同时引用ZBar和QQ授权登录SDK,由于二者均使用了Base64处理数据,XCode编译时报错: duplicate symbol _base64_e ...

  8. 使用 SharedPreferences 实现数据的存储和读取

    在开发的过程中我们必须遇到的就是如何对用户的数据进行有效的存储以及读取.我们举个例子,现在我们使用app,当我们登陆一个账号的时候选择记住密码软件就会记住我们的账号以及密码,我们退出当前账号,就可以直 ...

  9. NSFileManager文件操作的十个小功能

    NSFileManager文件操作的十个小功能 NSFileManager是一个单列类,也是一个文件管理器.可以通过NSFileManager创建文件夹.创建文件.写文件.读文件内容等等基本功能. 下 ...

  10. AOP这些应用场景(交叉业务)

    1.统计某个方法的性能,可以在每个业务方法执行前后 记录方法执行的当前时间,执行后的时间-执行前的时间= 方法执行时间.  这样就可以在开发过程中(项目未交付给客户前)统计程序的性能. 2.安全 ,权 ...