题目:http://community.topcoder.com/stat?c=problem_statement&pm=13275&rd=16008

由于图中边数不多,选择DFS遍历全部路径,计算路径Inversions时使用了一个R[] 数组,能够在O(N)时间内得到路径Inversions,又由于该图所以路径条数为O(N^2),算法复杂度为O(N^3),对于N为1000的限制来说,复杂度较高,但实际測试中,最慢的測试用例费时700多ms,没有超时。若要减小复杂度,须要更高效的算法来计算路径的Inversions,使用 Binary
indexed tree (BIT
)数据结构能够达到O(logN), 总复杂的减小到O(N^2logN)。

代码:

#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <iostream>
#include <sstream>
#include <iomanip> #include <bitset>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <set>
#include <map> #include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <ctime>
#include <climits>
using namespace std; #define CHECKTIME() printf("%.2lf\n", (double)clock() / CLOCKS_PER_SEC)
typedef pair<int, int> pii;
typedef long long llong;
typedef pair<llong, llong> pll;
#define mkp make_pair /*************** Program Begin **********************/
const int INF = 1000000000;
class GraphInversions {
public:
vector <int> V, A, B, adj[1001];
bool visited[1005]; // 顶点的訪问状态
int R[1005]; // 用于计算 Inversions, R[weight] 表示当前路径上权值为weight的顶点的个数
int N, K, ans;
void DFS(int u, int d, int invs)
{
if (d == K) {
ans = min(ans, invs);
} else if (d < K) {
for (int i = 0; i < adj[u].size(); i++) {
int w = adj[u][i];
if (visited[w]) {
continue;
}
visited[w] = true;
++R[ V[w] ];
DFS(w, d + 1, invs + accumulate(R + V[w] + 1, R + 1001, 0));
--R[ V[w] ]; // 将顶点从该路径排除
visited[w] = false; // 还有一条路径依旧能够使用该顶点
}
} }
int getMinimumInversions(vector <int> A, vector <int> B, vector <int> V, int K) {
int res = INF;
this->N = A.size();
this->V = V;
this->K = K; for (int i = 0; i < N; i++) {
adj[ A[i] ].push_back(B[i]);
adj[ B[i] ].push_back(A[i]);
} for (int i = 0; i < N; i++) { // 依次遍历全部顶点,以每一个顶点为起始点进行DFS
ans = INF;
memset(visited, 0, sizeof(visited));
memset(R, 0, sizeof(R));
visited[i] = true; // 这一步不要忘,起始点訪问状态应为TRUE
++R[ V[i] ]; // 将起始点增加到路径中
DFS(i, 1, 0);
res = min(res, ans);
}
return (res == INF ? -1 : res);
}
}; /************** Program End ************************/

SRM 627 D1L2GraphInversionsDFS查找指定长度的所有路径 Binary indexed tree (BIT)的更多相关文章

  1. Linux find查找指定文件 按照名称 然后cp拷贝到指定目录且指定文件名

    最近有一个需求,需要将指定目录下的文件(已知文件名)复制到另一个指定的目录且重命名文件. 要求: 在var目录下会定义系统的启动日志相关信息,请查找对应的boot.log文件,并把它备份一份到var/ ...

  2. 学underscore在数组中查找指定元素

    前言 在开发中,我们经常会遇到在数组中查找指定元素的需求,可能大家觉得这个需求过于简单,然而如何优雅的去实现一个 findIndex 和 findLastIndex.indexOf 和 lastInd ...

  3. SQL 通过syscolumns.xtype动态查找指定数据类型字段所包含的数据

    表中太多列,只想查找某些比如,数据类型为varchar的字段的数据. 思路:1.先获取列名: select * from syscolumns where id=(select max(id) fro ...

  4. .NET截取指定长度汉字超出部分以"..."代替

    /// <summary> /// 将指定字符串按指定长度进行剪切, /// </summary> /// <param name= "oldStr " ...

  5. Java-生成指定长度验证码的一种简单思路

     前言:以前做过的一个项目,刚开的时候始验证码是在前端生成前端验证的,后来觉得不靠谱,另外就是找回密码的功能也需要发送邮件和短信的验证码,所以,验证码就必须在后端生成并且保存到应用会话中才行了!所以, ...

  6. C++查找指定目录下所以指定类型的文件

    /*************************************************************** 函数名称:FindFile 查找指定目录下指定文件 输入:fileNa ...

  7. php随机生成指定长度的字符串 可以固定数字 字母 混合

    php 生成随机字符串 可以指定是纯数字 还是纯字母 或者混合的. 可以指定长度的. function rand_zifu($what,$number){ $string=''; for($i = 1 ...

  8. 菜鸟学Linux命令:lsof命令 查找指定用户、进程、端口打开的文件

    lsof,list open files, 是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件. 命令格式:ls ...

  9. asp.net截取指定长度的字符串内容

    /// <summary> /// 用于截取指定长度的字符串内容 /// </summary> /// <param name="sString"&g ...

随机推荐

  1. Objective-C开发编码规范:4大方面解决开发中的规范性问题

    Objective-C 编码规范,内容来自苹果.谷歌的文档翻译,自己的编码经验和对其它资料的总结. 概要 Objective-C 是一门面向对象的动态编程语言,主要用于编写 iOS 和 Mac 应用程 ...

  2. 驱动: 中断【1】linux中断流程

    通常情况下,当一个给定的中断处理程序正在执行时,所有其他的中断都是打开的,所以这些不同中断线上的其他中断都能被处理,但当前中断总是被禁止的. 将中断处理切为两个部分或两半.中断处理程序上半部(top ...

  3. html向servlet传乱码解决办法

    html 设置为utf-8格式 <meta http-equiv="content-type" content="text/html;charset=UTF-8&q ...

  4. django email用法

    在settings里面设置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'EMAIL_PORT = 25EMAIL_HOST ...

  5. CCIE路由实验(4) -- BGP路由控制

    1.过滤BGP路由的方法2.用AS-path filter控制路由3.用Community Filter控制路由 enableconf tno ip do loenable pass ciscolin ...

  6. 提高mysql查询效率的六种方法

    1,表设计一定要优化,冗余数据最少,少用连接查询.如果在实际应用中,使用了极其复杂的连接,子查询,则数据表的设计得要重新考虑了. 2,尽量用char而不是varchar,因为固定长度得string用起 ...

  7. python模块介绍- multi-mechanize 性能测试工具

    python模块介绍- multi-mechanize 性能测试工具 2013-09-13 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 3739 ...

  8. 测试DOM0级事件和DOM2级事件的堆叠

    1. 问题 如果大家看过北风网CJ讲师的Javascript视频教程,就可以看到其封装了一个很强的事件添加和删除函数,如下所示 function addEvent(obj, evtype, fn) { ...

  9. 当webview遇到了Slidingmenu,webView出现卡白,解决方案

    先介绍一下什么是SlidingMenu: Sliding Menu的是一种比较新的设置界面或配置界面效果,在主界面左滑或者右滑出现设置界面,能方便的进行各种操作.如Evernote.Google+.F ...

  10. Orleans-Hello World

    Orleans-Hello World http://www.rm5u.com/orleans/orleans-intro.html 什么是Orleans?          Orleans(奥尔良) ...