Codechef Bear and Clique Distances

题目:https://www.codechef.com/problems/CLIQUED

描述:共有N个点,前1—K个点任意两点之间有一条无向边,边的权值为X,再任意给M条边(u,v,w)(不重复),求任意一点到其余各点的最短路。

分析:

1.最短路算法(usual Dijkstra)+一点小变形(a little twist)

2.trick:设置一个变量upd=1;因为前K个点之前两两是连通的,所以当第一次到前K个点中任一点(假设为u)时,就可以更新得到前K个点的距离(除了u)d[i](i<=k)为d[u]+X。

即:1-K中任意一点作为中间点更新1-K之间其他点的距离只用更新一次,因为最短路算法中每次队列取出来的点都是当前剩下点中距离源点最近的点,还有就是下次再更新到1-K点中的点时不用再继续更新与该点相连的1-K点的距离了

3.复杂度:O((m+k)log(V))

4.边的权值范围到达1e9,前面WA了几次,因为初始化inf=1e9+10;值太小了,有很多边,假如所有边大小都是1e9,则路径长度加起来远远大于初始化位1e9+10的inf。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<vector>
  8 #include<queue>
  9 #include<map>
 10
 11 using namespace std;
 12 #define maxn 100000+10
 13 #define inf 1e15+10  //该题中inf定义为1e9+10 太小,导致出错
 14 #define ll long long
 15
 16 struct Edge{
 17     ll u,v,w;
 18     Edge(ll u=0,ll v=0,ll w=0):u(u),v(v),w(w){}
 19 };
 20
 21 struct Node{
 22     ll d,u;
 23     bool operator<(const Node& rhs)const{
 24         return d>rhs.d;
 25     }
 26 };
 27
 28 Edge edges[maxn];
 29 vector<ll>G[maxn];
 30 ll N,M,X,K,S;
 31 bool vis[maxn];
 32 ll d[maxn];
 33
 34 void Dijkstra()
 35 {
 36     bool flag=false;
 37     priority_queue<Node>Q;
 38
 39     for(int i=1;i<=N;i++) d[i]=inf;
 40     //memset(d,127,sizeof(d));
 41     memset(vis,0,sizeof(vis));
 42
 43     d[S]=0;
 44     Q.push(Node{0,S});
 45     while(!Q.empty())
 46     {
 47         Node x=Q.top();Q.pop();
 48         //cout<<x.d<<" "<<x.u<<endl;
 49         ll u=x.u;
 50         if(vis[u]) continue;
 51         vis[u]=true;
 52         if(u<=K && !flag)
 53         {
 54             flag=true;
 55             for(int i=1;i<=K;i++)
 56             {
 57                 if(i!=u && d[i]>d[u]+X)
 58                 {
 59                     d[i]=d[u]+X;
 60                     Q.push(Node{d[i],i});
 61                 }
 62             }
 63         }
 64         //cout<<G[u].size()<<endl;
 65         for(int i=0;i<G[u].size();i++)
 66         {
 67             ll id=G[u][i];
 68             //cout<<id<<endl;
 69             ll x1=edges[id].u,x2=edges[id].v,x3=edges[id].w;
 70             ll v=u==x1?x2:x1;
 71             if(d[v]>d[u]+x3)
 72             {
 73                 d[v]=d[u]+x3;
 74                 Q.push(Node{d[v],v});
 75             }
 76         }
 77
 78     }
 79
 80 }
 81
 82 int main()
 83 {
 84     int t;
 85     scanf("%d",&t);
 86     while(t--)
 87     {
 88
 89         scanf("%lld%lld%lld%lld%lld",&N,&K,&X,&M,&S);
 90         for(int i=1;i<=N;i++) G[i].clear();
 91         for(int i=0;i<M;i++)
 92         {
 93             ll a,b,c;
 94             scanf("%lld%lld%lld",&a,&b,&c);
 95             edges[i]=Edge(a,b,c);
 96             G[a].push_back(i);
 97             G[b].push_back(i);
 98         }
 99         //for(int i=1;i<=N;i++) cout<<G[i].size()<<" ";
100         //cout<<endl;
101         Dijkstra();
102
103         for(int i=1;i<=N;i++)
104             printf("%lld%c",d[i],i==N?‘\n‘:‘ ‘);
105     }
106     return 0;
107 }

时间: 2025-01-01 20:55:10

Codechef Bear and Clique Distances的相关文章

CodeChef FNCS (分块+树状数组)

题目:https://www.codechef.com/problems/FNCS 题解: 我们知道要求区间和的时候,我们用前缀和去优化.这里也是一样,我们要求第 l 个函数到第 r 个函数 [l, r] 的函数和,那么我们可以用 sum[r] - sum[l-1] 来求得. 由于这个数据量有点大,所以我们将函数分块. 例如样例: 1 3 有5个函数,那么我们分成3块.{ [1 3] , [2 5] }, { [4 5], [3 5] }, { [1 2] }.每一块对应都有一个sum ,这时如

Maximum Clique

Maximum Clique Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 92 Accepted Submission(s): 60   Problem Description Given a graph G(V, E), a clique is a sub-graph g(v, e), so that for all vertex

codechef营养题 第三弹

第三弾が始まる! codechef problems 第三弹 一.Motorbike Racing 题面 It's time for the annual exciting Motorbike Race in Byteland. There are N motorcyclists taking part in the competition. Johnny is watching the race. At the present moment (time 0), Johnny has taken

codechef 营养题 第一弹

第一弾が始まる! 定期更新しない! 来源:http://wenku.baidu.com/link?url=XOJLwfgMsZp_9nhAK15591XFRgZl7f7_x7wtZ5_3T2peHh5XXoERDanUcdxw08SmRj1a5VY1o7jpW1xYv_V1kuYao1Pg4yKdfG4MfNsNAEa codechef problems 第一弹 一.Authentication Failed原题题面Several days ago Chef decided to registe

bzoj4260: Codechef REBXOR

求异或maxmin一般用trie (二进制式的trie).query中找的是满足((x>>i)&1)^A=1,那么A=((x>>i)&1)^1:maxx=max(sumx,sumi)(i=[1,x]).(YY一下异或的性质 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #def

codeforces 653B B. Bear and Compressing(dfs)

题目链接: B. Bear and Compressing time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Limak is a little polar bear. Polar bears hate long strings and thus they like to compress them. You should al

codeforces 653A A. Bear and Three Balls(水题)

题目链接: A. Bear and Three Balls time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Limak is a little polar bear. He has n balls, the i-th ball has size ti. Limak wants to give one ball to each

TCO14 2C L2: CliqueGraph,graph theory, clique

称号:http://community.topcoder.com/stat?c=problem_statement&pm=13251&rd=16017 參考:http://apps.topcoder.com/wiki/display/tc/TCO+2014+Round+2C 假设用先计算出每条边,用邻接矩阵来表示图,然后用BFS或 Floyd-Warshall算法来计算距离的话.时间复杂度是O(N^3),会超时.依据题名的提示知要利用clique graph的性质来做.基本思想是在BFS的

CLIQUE 聚类算法以及Java实现+多线程

CLIQUE(Clustering In QUEst)是一种简单的基于网格的聚类方法,用于发现子空间中基于密度的簇.CLIQUE把每个维划分成不重叠的区间,从而把数据对象的整个嵌入空间划分成单元.它使用一个密度阈值识别稠密单元和稀疏单元.一个单元是稠密的,如果映射到它的对象数超过该密度阈值. CLIQUE识别候选搜索空间的主要策略是使用稠密单元关于维度的单调性.这基于频繁模式和关联规则挖掘使用的先验性质.在子空间聚类的背景下,单调性陈述如下: 一个k-维(>1)单元c至少有I个点,仅当c的每个(