慢点走 ,多喝水

 
 

常用链接

  • 我的随笔
  • 我的评论
  • 我参与的随笔

留言簿

  • 给我留言
  • 查看公开留言
  • 查看私人留言

随笔分类

  • ACM(5) (rss)
  • Project Euler (rss)
  • 平常学习(1) (rss)

随笔档案

  • 2013年5月 (5)
  • 2013年4月 (1)
  • 2012年6月 (1)
  • 2012年3月 (1)
  • 2011年10月 (1)

文章分类

  • 平常学习 (rss)

搜索

  •  

最新评论

  • 1. re: 为什么Scala对于一般函数严格要求指明参数类型的语言, 对于匿名函数却可以不用指明参数类型?[未登录]
  • Scala匿名函数类型为Function1或者Function2,在方法重载时匿名函数的参数类型不会被写入函数签名只要参数个数就行了,这就啃爹了,但是在调用时却严格要求参数类型了,不明白为什么这么设计
  • --XXX
  • 2. re: 最近真的被打击了,要发奋了[未登录]
  • 加油啊!没有想到你是这样一个细腻的孩子!
    小朱来过了啊~~
    加油啊!
    RUN!
  • --朱
  • 3. re: 最近真的被打击了,要发奋了
  • @C小加
    南京邮电
  • --笨蛋侦探
  • 4. re: 最近真的被打击了,要发奋了
  • 评论内容较长,点击标题查看
  • --zuhd
  • 5. re: 最近真的被打击了,要发奋了
  • 加油~共勉!
  • --毕达哥拉斯半圆

阅读排行榜

  • 1. hdu 2586(2819)
  • 2. hdu 2433(2392)
  • 3. 最近真的被打击了,要发奋了(2183)
  • 4. hdu 2377 (1800)
  • 5. 差分约束(1700)

评论排行榜

  • 1. 最近真的被打击了,要发奋了(9)
  • 2. 为什么Scala对于一般函数严格要求指明参数类型的语言, 对于匿名函数却可以不用指明参数类型?(1)
  • 3. hdu 2586(0)
  • 4. hdu 2377 (0)
  • 5. hdu 2433(0)

Powered by: 博客园
模板提供:沪江博客
C++博客 | 首页 | 发新随笔 | 发新文章 | 联系 | 聚合 | 管理

置顶随笔

[置顶]有朋友真好
有朋友真好。
其实有时候只是想说说话,不是内心真的有疑问想寻求办法,因为答案其实就在自己心中,自己心里明白得很......但人就是这样,就算心里明白,也还是觉得憋,想找个人倾述。所以这时候,有朋友真好。朋友可以无偿地陪你,听你说话,跟你说话。
我今天其实也没发生什么,只是想了一些东西,心情就变得不太愉快,但并不是不愉快,只是很想有个人骂一下自己!骂自己的不成熟,骂自己没毅力,骂自己禁受不住挫折。然后我就找秦程聊天,聊着聊着,就释怀了,就开朗了。
有朋友真好。我没有好的文笔给解释这句话。
我对亲近的人都不轻易说谢谢,但今天我对秦程说了声谢谢,因为今天打电话的时候我想到blue 跟我说的一句话:有朋友真好。
posted @ 2012-03-17 11:37 笨蛋侦探 阅读(231) | 评论 (0) | 编辑 收藏
 
[置顶]最近真的被打击了,要发奋了
昨天ACM协会的学长们去南理工参加南理邀请赛,我和朱彦沛去打酱油了。
虽说是打酱油,但还是挺期待的。可是结果我们队(队名Run,就是我和彦沛两人)没Ac一道。。。有点失落。
再想起前段时间RQNOJ的月赛,只得了10分。
这段日子被打击了。
哎,我还远远不够呢。


#include<反思>
反思()
{ int keroro;
    case1:由于自己有noip基础,所以心里就有点骄傲感,我觉得这是我对待ACM心态不正的很大一个原因;
        solution:摆正好心态。看人家大牛们,多谦虚多低调呀,我就一个小毛孩还有什么资格去装逼?!
                 不想被别人、被自己看不起的话就要低调点,努力学习!
    case2:心猿意马,什么都像学,linux,批处理,Java,C#,robot等等什么鬼东西都想学,可是又没有耐心去一个人
          好好学,导致什么都不精。
        solution:先弄好ACM吧,linux也弄,反正现在linux上不了网,想玩也没来玩,所以主要放在ACM。
    case3:做题效率太低,缺少比赛经验。做题老是不喜欢自己弄数据调试,都是直接检查code,但这样很难发现
          一些漏洞。
        solution:学调试,开始学习弄测试数据。
    case4:没有复习,缺乏反思,以前做过的题拿到现在也不一定能A。这也是学习效率不高的很大的原因。
        solution:要经常反思,经常复习,做完题要写上必要题解!
    case5:没有钻研精神,即没有肥猫那种“一定要弄清楚”和“为什么这一定是最优解”的劲头。极度缺。
        solution:静下心来,试着耐着性子去钻研一下深一点的东西!加强“打破砂锅问到底”的精神。
    printf(
"加油!王国真");
    
return 0;
}


肥猫,我会超越你的!      
posted @ 2011-10-30 11:26 笨蛋侦探 阅读(2183) | 评论 (9) | 编辑 收藏
 

2013年5月31日

差分约束
差分约束(difference constraints),对,两个关键字要理解好,“difference”简单理解就是两个节点的“差”,对应的就是图中的边权,而“约束”对应的是图的边。这个图的边权不一定都是正数,之前我一直很奇怪为什么做最短路的时候初始化dis[]为了0也可以,那是因为我没意识到边权可以为负数,而思维定势地想初始化dis[]为0,那0不就是最小路径了吗,但这里差分约束的最短路径常常是负数的,所以最短路径可以不是0!!
看网上讲解的时候要小心,很多人把最长路和最短路是不分的,乱死了。
还有很重要的一点很多人没区分开,
    求最小可行解 ==> 把不等式划为dv >= dx + Z的形式,即建立<u,v,Z>边 ==> 可行解要最小,其实就是取约束条件中`最大`的约束 ==> 求最长路
    解释:为什么求最小可行解要划成dv >= dx + Z形式?因为这个形式暗指了“让dv尽量小”,因为此刻dv的取值区间为[du+Z, ∞]。
          为什么可行解最小,即意味着取最大约束条件?这样想,如果有dv >= du + Z1, dv >= du + Z2,(Z1<Z2),那dv的最小取值就是du+Z2,因为du+Z1不满足第二个约束条件。
          最后一步就好理解了,因为建图的边权就是约束值,既然上一步指要取最大约束,那当然是求最长路啦。
          网上很多讲解没有区分开所谓的最大/最小,一会儿指可行解的最,一会儿指约束条件的最,弄得我乱了好久。
  顺便贴一下:
    求最大可行解 ==> 把不等式划为dv <= dx + Z的形式,即建立<u,v,Z>边 ==> 其实就是取约束条件中`最小`约束 ==> 求最短路
    关于源点:很多时候额外价格源点可以帮我们把一个非连通图变成连通图,而对于源点的不等式,一定要和你之前建边时的不等式形式一样,如果之前是dv >= du + Z,那源点也要dv >= d0 + xxx。这个xxx就是dis[]的初始值,关于如何选取xxx,下面两句话摘自百度百科:
    “
     1.如果将源点到各点的距离初始化为0,最终求出的最短路满足 它们之间相互最接近了
     2.如果将源点到各点的距离初始化为INF(无穷大),其中之1为0,最终求出的最短路满足 它们与该点之间相互差值最大。
    ”
    差分约束题目我一般是用SPFA+栈,为什么不用dijkstra+heap?因为dijkstra不能处理负环,而我们的题目可能有负环,所以干脆都用SPFA了,多数条件下,用stack的SPFA比用queue的快,why?因为常常地,用最先更新了的点去更新其它点,效果比用以前已经更新了的点(在queue的tail)好。
差分约束专题:http://972169909-qq-com.iteye.com/blog/1185527
poj 1201  差分约束
题意:求符合题意的最小集合Z的元素个数,约束条件:i j C,表区间[i,j]至少有C个Z集合的元素。
隐含条件是,S区间是个连续的数字区间,0 <= s[i+1] - s[i] <= 1,其中s[i]表0~i中有多少数字是Z集合元素。下面是隐含条件的建边。
    for(int i = 0; i < 50001; i++) {    //@
        vert[i].push_back(i+1); edge[i].push_back(0);
        vert[i+1].push_back(i); edge[i+1].push_back(-1);
    }
poj 1364  差分约束
题意:约束条件:i, n, op, K --> op分greater和less,需要满足Si + S[i+1] + S[i+2] + ... + S[i+n] > K (或小于)
因为我是用dis[i]表示S0+S1+...+Si的和,所以<u,v,w>应该表示的意思是sum[v]-sum[u-1] = w,所以这里0也是一个点,所以源点不能取0!
//@ ?? 我在SPFA后面输出了dis[]数组来看,这些值并不符合题目的要求,那为什么整个程序是对的?如果要输出一个解的话怎么写?
    答:因为这里的dis[i]表示的是s1+s2+...+si的和,用第一个样例来说,
    sample input:
        4 2
        1 2 gt 0
        2 2 lt 2
    输出的dis[0--n] : -1 0 0 0 0
    s1+s2+s3 = sum[3] - sum[1-1] = dis[3] - dis[0] = 1 , 满足gt 0
    s2+s3+s4 = sum[4] - sum[2-1] = dis[4] - dis[1] = 0 , 满足lt 2
    所以,{si}的一组解应该为0,1,0,0,0.
poj 1983    差分约束
题意:给出两种约束条件,一种是P A B X,意为精确地约束A比B远X个单位;另一种V A B,意为模糊地约束A至少比B远1个单位。是否有可行解?
好点:两种约束条件,其中Precise约束可以转换为X <= A-B <= X
      有V i i 这种数据,这种数据在SPFA里会WA,在ballman_ford里AC,不过预处理一下就可以了,还是用SPFA.
hdu 3666  差分约束
题意:给出矩阵{Cij},问是否存在数列{A} 和 {B},使得对于矩阵内所有Xij满足: L <= Xij * Ai / Bj <= U 
构图。用log把乘除变成加减,就可以差分约束来做了。我用的是SPFA+stack求最短路,最长路应该也是可以的。没有建源点,直接一开>始把所有点push进去...  14xx ms 过挺险的~
posted @ 2013-05-31 11:25 笨蛋侦探 阅读(1700) | 评论 (0) | 编辑 收藏
 

2013年5月28日

查分约束 poj 3159
做第一道查分约束poj 3159...TLE不断。估计管理员是跟C++的STL过不去,就卡用vector的人了。。而我已经好久好久没人工写什么邻接表,前向星什么的了,就只能TLE过不了了。。换了什么dijkstra+优先队列,SPFA+stack优化,只要用vector来存边,估计都过不了。
下面是TLE代码,留纪念。
#include <string.h>
#include <stdio.h>
#include <vector>
using namespace std;
int n, m;
int dis[30001];
bool visit[30001];
int S[30001], S_top = 0;
vector<int> vert[30001], edge[30001];
void dijkstra(int s);
int main()
{
    int u,v,w;
    scanf("%d%d", &n, &m);
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        vert[u].push_back(v);
        edge[u].push_back(w);
    }
    dijkstra(1);    //最长路-----不是的,是最短路!
    printf("%d\n", dis[n]);
}
void dijkstra(int s)
{
    memset(dis, 127, sizeof(dis));
    dis[s] = 0;
    visit[s] = true;
    S[++S_top] = s;
    while(S_top > 0) {
        int u = S[S_top--];
        visit[u] = false;
        for(int Size = vert[u].size(), i = 0; i < Size; i++) {
            int v = vert[u][i];
            if(dis[v] > dis[u] + edge[u][i]) {
                dis[v] = dis[u] + edge[u][i];
                if(visit[v] == false) {
                    S[++S_top] = v;
                    visit[v] = true;
                }
            }
       }
   }
}
posted @ 2013-05-28 15:51 笨蛋侦探 阅读(178) | 评论 (0) | 编辑 收藏
 

2013年5月27日

hdu 2433
/*
    最短路  好题
    
    题意:给出边建图,然后分别删除各条边,问每一次删边后的所有端点的两两最短路之和,若有一对端点不连通,则返回INF
    思路:暴力解法是每次删边后都来n次最短路。这里面的冗余就是删除的边并不影响一些点的最短路树,所以这些点可以不用在删边后都来次dijkstra>。标程解法就是在暴力解法上加上一些剪枝。先预处理出所有点的最短路树,记x的最短路树的和为sum[x]。现在来去掉冗余:在预处理时用used[x][u][v]记录点x的最短路树是否用到了边u--v,则删除边u--v的时候,判断点x的最短路树是否用到边u--v的,若用到,则对x做一次dijkstra,用新的sum[x]表示>当前最短路树;否则用预处理的sum[x]就可以,不用再dijkstra.
    dijkstra是利用`边权为1`这一特性来加快的版本,具体看:http://www.cppblog.com/keroro/archive/2013/05/27/200621.html
    这道题有很多重边,这估计也是考点之一,不好好处理重边的话会超时。


    多数题解是错的,因为hdu上的这道题的数据比较水才可以过,可以试试discuss里给的数据,下面这几个题解比较靠谱。
    http://blog.csdn.net/nash142857/article/details/8253913
    http://www.cnblogs.com/crisxyj/archive/2013/03/10/2952396.html
    http://hi.baidu.com/novosbirsk/item/bfcf0cd201edfc2d39f6f709
    两份代码的思想是完全一样的,只是“baidu blog”那份用w[i][e]来判断i的最短路树是否包括边e,而cnblog的那份是用used[x][u][v]来判断边u-->v是否xxx.
*/

#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <deque>
using namespace std;
#define     MAXN    101
#define     INF     99999999
#define     debug   printf("!\n")
struct Edge { int u,v; } edge[3001];
vector<int> vertex[MAXN];
int visit[MAXN], sum[MAXN], cnt[MAXN][MAXN];        //cnt[u][v]表u--v的边有多少条,用来处理重边
bool used[MAXN][MAXN][MAXN];                        //used[x][u][v]x的最短路树是否用到了边u--v
int n, m;

void init();
void dijkstra(int s, int when, int flag);
int main()
{
    int when = 0;
    int u, v;
    while(scanf("%d%d", &n, &m) != EOF) {
        init();
        for(int i = 0; i < m; i++) {
            scanf("%d%d", &u, &v);
            vertex[u].push_back(v);
            vertex[v].push_back(u);
            edge[i].u = u, edge[i].v = v;
            cnt[u][v]++, cnt[v][u]++;
        }
        int ans = 0;
        for(int i = 1; i <= n; i++) {
            dijkstra(i, ++when, 1);
            ans += sum[i];
        }
        for(int i = 0; i < m; i++) {
            int tmp = ans;
            int u = edge[i].u, v = edge[i].v;
            //forbid_u = edge[i].u, forbid_v = edge[i].v;       因为有重边所以不能用这种方法
            for(int j = 1; j <= n; j++) if(used[j][u][v] && cnt[u][v] == 1) {       //不加cnt[u][v] == 1会超时。。卡的就是重边,靠!
                int tmp = sum[j];
                sum[j] = 0;
                //vector<int> :: iterator it1 = find(vertex[u].begin(), vertex[u].end(), v);
                
//vector<int> :: iterator it2 = find(vertex[v].begin(), vertex[v].end(), u);
                
//*it1 = u, *it2 = v;
                cnt[u][v]--, cnt[v][u]--;
                dijkstra(j, ++when, 2);
                cnt[u][v]++, cnt[v][u]++;
                //*it1 = v, *it2 = u;     //本来是用erase的,超时了。 现在换这种方法也超时了,估计find耗时太久。
                ans = ans - tmp + sum[j];   //用新的sum[j]来代替旧的tmp
                sum[j] = tmp;
                int k ;
                for(k = 1; k <= n; k++) if(visit[k] != when) break;     //如果删边了以后j不能到达k(即k没有进过队)
                if(k <= n) {
                    ans = INF;
                    break;
                }
            }
            ans == INF ? printf("INF\n") : printf("%d\n", ans);
            ans = tmp;  //不要把这个tmp和for_j里的tmp混了..
        }
        for(int i = 0; i < m; i++) cnt[edge[i].u][edge[i].v] = cnt[edge[i].v][edge[i].u] = 0;   //初始化因为感觉memset(cnt)会不会花更多时间
    }
    return 0;
}
void dijkstra(int s, int when, int flag)
{
    int floors = 1;
    int cur = 0;
    deque<int> Q[2];
    Q[cur].push_back(s);
    visit[s] = when;
    do {
        while(!Q[cur].empty()) {
            int u = Q[cur].front();
            Q[cur].pop_front();
            for(int Size = vertex[u].size(), i = 0; i < Size; i++) {
                int v = vertex[u][i];
                if(visit[v] != when && cnt[u][v] > 0) {
                    if(flag == 1) used[s][u][v] = used[s][v][u] = true;   //第一次最短路才标记used因为懒得写两遍,所以要flag来标记是删边前还收删边后做的最短路,1则是预处理时的最短路,此时要标记used;2则是删边后的最短路,这个时候不能标记used.
                    visit[v] = when;
                    sum[s] += floors;
                    Q[1-cur].push_back(v);
                }
            }
        }
        floors++; 
        cur = 1 - cur;
    } while(!Q[cur].empty());
}
void init()
{
    memset(sum, 0, sizeof(sum));
    memset(used, false, sizeof(used));
    for(int i = 1; i <= n; i++) vertex[i].clear();
}
posted @ 2013-05-27 17:56 笨蛋侦探 阅读(2392) | 评论 (0) | 编辑 收藏
 
hdu 2377
/*
    最短路, 终点集合到s的最远距离最短,求s.    即已知终点集{d}求一s使得Min{ max{ dis(s, di) } }
    好题
    
  
  
    思路:  多次单源最短路,选出最大值
            在对每个x进行分层搜索的过程中, 用max_d[y]记录每个地区x到达地区y的最短距离中的最大值. 最后求得的Star Value就是max_d[]中的最小值.
            由于题目的特殊性`边权都为1`,所以可以借助这一性质变换一下SPFA使其更快。
            说个题外话,在临高时看到有个学弟拓扑排序用到“分层思想”,一直觉得很妙。就是拓扑后我们可以得到floor[i],如果floor[i] > floor[j],即说明j是i的前驱节点(层数越小越接近root); 而floor[i] == floor[j]的话则i,j的相对顺序无所谓,因为他们都在“同一层”。
            这里因为边权都为1,所以SPFA可以用到上述的分层思想,层数越高,离source越远。代码里面floors就表示层数,Q是滚动队列,就是一层一层地relax后继节点。
            注意!!千万不要以为max_d[]是最短路算法里面的dis[],这里的max_d[i]是到点i到终点集合{di}的最大值!而常规最短路算法里的dis[]已经被省略为“层数”了,不需要记录,所以没开数组。
            最重要的是学到一个tip!!以前我做多次最短路的时候总要每次都初始化visit[] -> false,但其实不用的,我们只要用一个变量when表示“这是第几次做SPFA(或其他)“,然后每次入队前都看”是否当前visit[v] == when就可以直到改点是否已经入过队......
*/
#include <stdio.h>
#include <string.h>
#include <vector>
#include <deque>
using namespace std;
#define     debug   printf("!\n")
#define     INF     999999999
#define     MAXN    10000
int n;
int max_d[MAXN];
int visit[MAXN];
vector<int> v[MAXN];

void SPFA(int s, int when);
void init();
int main()
{
    int cases, query, id, m, y, x;
    scanf("%d", &cases);
    while(cases--) {
        scanf("%d%d", &n, &query);
        init();
        for(int i = 0; i < n; i++) {
            scanf("%d%d", &id, &m);
            while(m--) {
                scanf("%d", &y);
                v[id].push_back(y);
            }
        }
        int when = 0;
        while(query--) {
            scanf("%d", &m);
            while(m--) {
                scanf("%d", &x);
                SPFA(x, ++when);
            }
        }
        
        int ans = INF, ans_id = -1;
        for(int i = 1; i < MAXN; i++) if(!v[i].empty() && max_d[i] < ans) ans = max_d[i], ans_id = i;
        printf("%d %d\n", ans, ans_id);
    }
    return 0;
}
void init()
{
    for(int i = 0; i < MAXN; i++) v[i].clear();
    memset(max_d, 0, sizeof(max_d));
    memset(visit, 0, sizeof(visit));
}
void SPFA(int s, int when)
{
    deque<int> Q[2];
    int cur = 0;
    Q[cur].push_back(s);
    max_d[s] = max(max_d[s], 1);
    visit[s] = when;
    int floors = 1;             
    do {
        floors++;
        while(!Q[cur].empty()) {
            int at = Q[cur].front();
            Q[cur].pop_front();
            for(int Size = v[at].size(), i = 0; i < Size; i++) {
                int to = v[at][i];
                if(visit[to] != when) {     //是否已入队
                    
//max_d[to] = max(max_d[to], max_d[at]+1);      这句是不对的,因为这个分层跟拓扑排序的分层是不一样的,拓扑排序是要在入度为0时才能加进队Q,所以可以这样写,但是这里只要第一次遇见点to就必须得入队,因为要的是最短路径
                    max_d[to] = max(max_d[to], floors); //不把这句放在if外面,因为这里的max_d[to]是距离s的最短路径,最短路径也就是最小层数,最小层数在to第一次入队的时候已经得到了
                    visit[to] = when;
                    Q[1-cur].push_back(to);
                }
            }
        }
        cur = 1 - cur;
    } while(!Q[cur].empty());
}
posted @ 2013-05-27 17:52 笨蛋侦探 阅读(1800) | 评论 (0) | 编辑 收藏
 

2013年5月17日

hdu 2586
/*
    最小公共祖先
    题意: 给出一颗无向有边权树, 询问若干个(u,v)对的距离.


    所谓LCA 的Tarjan算法, 实际上就是在建树的过程中把query中的lca给计算出来, 所以称为`离线算法` . 是的, 本质就是这么简单, 好多解释都搞复杂了.

    步骤略, 自己google.
    理解这个算法一定要抓住`递推`的思想(也有递归在里面, 也要抓住).
    Tarjan是利用并查集实现的, 在递推过程中, 一棵树的root节点代表这棵树(联系并查集来想), 这样做的好处是, 如果问点i与j的lca, 我们只要找i,j都属于的最小的哪棵子树就行了, 因为该子树就是我们的答案. 那如何确定是那颗子树呢? 这一点后面再解释一下.
    下面说Tarjan最巧妙的点了. 因为是在建树的过程中计算所有query, 也就表示我们此刻是否能计算某一query对(u,v)的条件是 : u和v是否都已经遍历过. 所以我们可以在遍历到点v(假设经历v的时间比u晚)的时候把query给计算出来. 比如lcm(u,v)就是find(u). 那此刻的find(v)和lcm(u,v)相不相等呢? 答案是不相等, 至少在我的代码实现上不相等. 因为father[x]的更新是在`递归回去`的时候更新的, 而此刻在遍历v点, 还没递归回去呢, father[v]当然也就没更新啦.
    其实上一段就已经回答了`如何确定哪棵子树是我们想要的答案`这一问题了. 就是find(u)所代表的子树! 注意, 是find(u), 不是find(v)! 因为u是在v之前已经被遍历过了, 并且递归回去过sub_root过了, 也就是father[u]被更新为sub_root了, 所以find(u)可以代表当前的sub_tree, 即`最小包含(u,v)子树`

下面两个解释, 推荐一下. 罗嗦一句, 看代码更容易理解, 人脑模拟一遍更容易理解
    
http://www.nocow.cn/index.php/Tarjan%E7%AE%97%E6%B3%95
    
http://blog.chinaunix.net/uid-1721137-id-181005.html
*/
#include <vector>
#include <stdio.h>
using namespace std;
#define     MAXN    40001
#define     debug   printf("!\n")
vector<int> v[MAXN], w[MAXN], query[MAXN], ans_num[MAXN];
int father[MAXN], dis[MAXN], ans[201];
bool visit[MAXN];
int n;

void init()
{
    for(int i = 1; i <= n; i++) {
        v[i].clear();
        w[i].clear();
        ans_num[i].clear();
        query[i].clear();
        father[i] = i;
        dis[i] = 0;
        visit[i] = false;
    }
}

int find(int x) 
{ 
    return x == father[x] ? x : father[x] = find(father[x]); 
}
void Union(int x, int y) { father[find(y)] = find(x); }
void Tarjan(int now, int value)
{
    visit[now] = true;
    dis[now] = value;
    for(int Size = v[now].size(), i = 0; i < Size; i++) {
        int tmp = v[now][i];
        if(visit[tmp] != 0) continue;
        Tarjan(tmp, value + w[now][i]);
        Union(now, tmp);            //注意顺序, 先Tarjan子节点tmp, 再更新其father[tmp], 因为要保证在递推tmp所代表的子树时, father[tmp] = tmp, 而与当前子树无关. 递归回来的时候再把tmp代表的子树`并入`到当前树里
    }

    for(int Size = query[now].size(), i = 0; i < Size; i++) {
        int tmp = query[now][i];
        if(!visit[tmp]) continue;       //若visit[tmp] == true, 即表示tmp节点已经遍历过, 此时可计算相应的query
        ans[ans_num[now][i]] = dis[now] + dis[tmp] - 2 * dis[find(tmp)];
    }
}

int main()
{
    int cases, Query, x, y, z;
    scanf("%d", &cases);
    while(cases--) {
        scanf("%d%d", &n, &Query);
        init();
        for(int i = 1; i < n; i++) {
            scanf("%d%d%d", &x, &y, &z);
            v[x].push_back(y);
            w[x].push_back(z);
            v[y].push_back(x);
            w[y].push_back(z);
        }

        for(int i = 0; i < Query; i++) {
            scanf("%d%d", &x, &y);
            query[x].push_back(y);
            query[y].push_back(x);
            ans_num[x].push_back(i);
            ans_num[y].push_back(i);
        }
        Tarjan(1, 0);
        for(int i = 0; i < Query; i++) printf("%d\n", ans[i]);
    }
    return 0;
}
posted @ 2013-05-17 02:44 笨蛋侦探 阅读(2819) | 评论 (0) | 编辑 收藏
 

2013年4月4日

为什么Scala对于一般函数严格要求指明参数类型的语言, 对于匿名函数却可以不用指明参数类型?
在coursera上上看了两周的Scala, 刚才奇怪为什么Scala对于一般函数严格要求指明参数类型的语言, 对于匿名函数却可以不用指明参数类型? google无果. 不想查了. 习惯了Scheme/SML这样有类型推导系统的语言, 再来写Scala有点排斥心理, 而且Scala更过分的是要连函数的返回类型也要写...喂喂, 这都完全丧失了FP的美感了吧 >_< 突然想起来, 昨天才发现SML内置没有对大数的操作---好失望~ 当初选这门课是好奇它能把面向对象与函数式能结合到多大程度, 现在看来没什么令人惊奇的, 不贬不赞. 还是原生函数式语言比较好玩. 如果你是被标题骗过来的, 能回答标题的问题就请给我讲讲吧~谢谢!
posted @ 2013-04-04 22:28 笨蛋侦探 阅读(905) | 评论 (1) | 编辑 收藏
 

2012年6月10日

与秦程QQ聊天,学到很多东西!
今天跟秦程QQ聊天,受到了些许启发。
秦,大学的他真的见识到了很多东西,学到很多东西,成长了好多!说实话,我羡慕了。
是的,我羡慕了,秦这一年的成长量。这是他自己争取来的!而我,做的远远不够!
觉得我的朋友们,都好了不起!大家都在成长,都在努力!有留级危险的鑫鑫,昨天被部长踢的丹妮,今天因为画坏了而抱怨的关业培,在跟我聊得秦程,还有还有,玉猪,宣卓,李璐雨。。。等等。让我想起了高中同桌猪魁,他曾经有段时间很努力!沈天弋,沈竹筠。。。鸣人,小李,四代火影。。。他们,都在,努力。
努力!

聊天记录
交谈中请勿轻信汇款、中奖信息、陌生电话,勿使用外挂软件。

秦程  
22:10:45
黑子的篮球漫画超级好看!
笨蛋侦探  
22:11:48
。。。真心不想看漫画,宁愿等动画吧
~~
看《康熙来了》,挺疯的
~
秦程  
22:12:31
我觉得漫画好看多了,,而且我觉得动画没那么长。。。后面各种热血呀
笨蛋侦探  
22:13:05
动画有偷工减料之嫌。。。
其实不是很喜欢黑子的篮球
秦程  
22:13:48
还行吧,,漫画出了挺长了,非常好看,昨晚看了一百多卷。。。
我倒是很喜欢
笨蛋侦探  
22:14:22
好奢侈。。。你不觉得好看的漫画一下子看了一百多卷。。。
秦程  
22:14:31
呵呵
感觉就像我这个学期的缩影,这部漫画,充满尊严,挣扎,有种从地狱爬回来的感觉
笨蛋侦探  
22:15:49
哦
~
一百多卷
秦程  
22:16:38
热血,很爽
特别是打奇迹的世代最强的人那段,太爽了
笨蛋侦探  
22:17:51
现在看古龙的书,也挺热血。。。and漫画,为什么你会有这么的兴致一下子看这么长的漫画呀
秦程  
22:18:13
因为就像看我自己呀
笨蛋侦探  
22:19:03
理解。看到自己的身影总是会很喜欢吧。
黑子的动画是不是比漫画挫了?
秦程  
22:20:04
还好。。。不过漫画很不错,动画也可以了,还原的很多了
笨蛋侦探  
22:20:55
是吗
~感觉跟食梦者一样,热血是热血,但是进展太快。
所以看起来有偷工减料的感觉。
秦程  
22:21:36
我很理解当时那个人出现的识货的绝望,觉得自己即使尽所有的力量也无法打倒的感觉,这个时期,我真的遇到过很多这个人
笨蛋侦探  
22:23:30
遇到得越多,越知道自己的渺小,越会往强大的方向跑。
所以你能遇到他们,真的是很幸运!
不是每个人都有遇到强人的机会的。
秦程  
22:25:01
呵呵呵
秦程  
22:26:39
其实我还知道另一个道理,就是我一个人是赢不了的
笨蛋侦探  
22:28:31
我会好好体会着句话,“一个人是赢不了的”。
我这一年,似乎都是一个人做的,感觉很不好。
笨蛋侦探  
22:30:01
其实之前就挺遗憾的,一年了,自己还没什么团队之类的东西。
秦程  
22:30:06
我也是受一群人感染
我第一次明白有种东西叫“热爱”,真的被震撼到了
笨蛋侦探  
22:31:07
热爱。。。
秦程  
22:32:22
他们告诉有的事无关胜负却事关尊严,这里面和黑子里面的很像
笨蛋侦探  
22:32:49
嗯。尊严最重要。
秦程  
22:33:52
第一次因为失败而落泪,也是第一次因为获胜而落泪,也是第一次觉得自己这么能哭
笨蛋侦探  
22:34:57

看不到,不过,加油!
笨蛋侦探  
22:36:02
大学你见识了好多,成长了好多!
秦程  
22:36:25
不过是输的比较多而已
笨蛋侦探  
22:36:46
给了我一些启发。
秦程  
22:38:27
可没那么容易,,,,我也只能这么说了。。。
笨蛋侦探  
22:38:49
嗯。
秦程  
22:41:32
要去获得尊重,这远比胜负重要
笨蛋侦探  
22:41:51
说实话,突然羡慕你这一年的成长量!为你高兴。
这是你努力得来的。
秦程  
22:43:58
这是拿尊严换来的。。。不知道你能不能理解。。
秦程  
22:48:22
好吧,,,别多想
笨蛋侦探  
22:49:10
我觉得,真的学到了东西。    因为我没有你这种经历。
秦程  
22:49:31
。。。你会明白的
posted @ 2012-06-10 22:52 笨蛋侦探 阅读(365) | 评论 (0) | 编辑 收藏
 

2012年3月17日

有朋友真好
有朋友真好。
其实有时候只是想说说话,不是内心真的有疑问想寻求办法,因为答案其实就在自己心中,自己心里明白得很......但人就是这样,就算心里明白,也还是觉得憋,想找个人倾述。所以这时候,有朋友真好。朋友可以无偿地陪你,听你说话,跟你说话。
我今天其实也没发生什么,只是想了一些东西,心情就变得不太愉快,但并不是不愉快,只是很想有个人骂一下自己!骂自己的不成熟,骂自己没毅力,骂自己禁受不住挫折。然后我就找秦程聊天,聊着聊着,就释怀了,就开朗了。
有朋友真好。我没有好的文笔给解释这句话。
我对亲近的人都不轻易说谢谢,但今天我对秦程说了声谢谢,因为今天打电话的时候我想到blue 跟我说的一句话:有朋友真好。
posted @ 2012-03-17 11:37 笨蛋侦探 阅读(231) | 评论 (0) | 编辑 收藏
 

2011年10月30日

最近真的被打击了,要发奋了
昨天ACM协会的学长们去南理工参加南理邀请赛,我和朱彦沛去打酱油了。
虽说是打酱油,但还是挺期待的。可是结果我们队(队名Run,就是我和彦沛两人)没Ac一道。。。有点失落。
再想起前段时间RQNOJ的月赛,只得了10分。
这段日子被打击了。
哎,我还远远不够呢。


#include<反思>
反思()
{ int keroro;
    case1:由于自己有noip基础,所以心里就有点骄傲感,我觉得这是我对待ACM心态不正的很大一个原因;
        solution:摆正好心态。看人家大牛们,多谦虚多低调呀,我就一个小毛孩还有什么资格去装逼?!
                 不想被别人、被自己看不起的话就要低调点,努力学习!
    case2:心猿意马,什么都像学,linux,批处理,Java,C#,robot等等什么鬼东西都想学,可是又没有耐心去一个人
          好好学,导致什么都不精。
        solution:先弄好ACM吧,linux也弄,反正现在linux上不了网,想玩也没来玩,所以主要放在ACM。
    case3:做题效率太低,缺少比赛经验。做题老是不喜欢自己弄数据调试,都是直接检查code,但这样很难发现
          一些漏洞。
        solution:学调试,开始学习弄测试数据。
    case4:没有复习,缺乏反思,以前做过的题拿到现在也不一定能A。这也是学习效率不高的很大的原因。
        solution:要经常反思,经常复习,做完题要写上必要题解!
    case5:没有钻研精神,即没有肥猫那种“一定要弄清楚”和“为什么这一定是最优解”的劲头。极度缺。
        solution:静下心来,试着耐着性子去钻研一下深一点的东西!加强“打破砂锅问到底”的精神。
    printf(
"加油!王国真");
    
return 0;
}


肥猫,我会超越你的!      
posted @ 2011-10-30 11:26 笨蛋侦探 阅读(2183) | 评论 (9) | 编辑 收藏
 
仅列出标题