10.15T2 生成树+非树边暴力

Description

在这一切发生之前,学园都市表面看起来其实是非常平静的。但仅仅只是表面而已。例如第五市场下面的地下街又传来了哔哩哔哩的声音,很显然,这是电击使在使用能力,而她的面前站着一个抬起右臂的少年。为什么放电妹要去攻击刺猬头?通过御坂美琴,我们可以知道,刺猬头——上条当麻在大霸星祭的时候输掉了和御坂美琴的赌约。
作为惩罚游戏,上条当麻这一天要无条件接受美琴的所有条件。而上条当麻趁御坂美琴在办理他们两人的双人通话套餐的一小会儿时间,又“勾搭”上了御坂妹。
在御坂妹和最后之作离开过后,御坂美琴拉着上条当麻去了地下街的游戏厅。现在的美琴小姐十分气氛,因为总有人来打扰她和上条当麻的私会。上条当麻现在也发现了这个问题,正在(被迫)想如何让美琴开心。这时,一台崭新的街机出现在他们面前,而最终大奖是一个3米长的呱太玩偶。此时的美琴,早已准备跃跃欲试,可当麻却突然挡在了他的面前,“这次就让我来吧!(被迫)”
这台游戏机里面的游戏是一个十分无聊的游戏:首先,屏幕上面会出现一张多个点多条无向边的图,两点之间最多只会有一条边,且这张地图是不会有自环的。每条边的权值也标在了图上。每一关,屏幕上会给出两点,让你在三秒之内答出这两点之间的最短距离。游戏保证两点之间一定有边。
作为无能力者(bug 者),当麻的计算能力肯定没有美琴强,但他也不像在美琴面前出丑。所以他悄悄地找到了来自于BSKingSchool 的你,让你帮他计算一下游戏的答案。

Input

第一行为两个整数 n,m。表示地图的点数和边数。
第二行到第m+1 行,每行三个整数 x,y ,z ,表示 x,y 两点之间存在一条直接路径,长度为z 。
第m+2 行为一个整数 q,表示机器给出了q 个提问。
第m+3 行到第m+3+q 行,每行二个整数 a,b 。表示机器所给出的两点。

Output

共q行,每行一个数表示答案。

Sample Input

3 3 1 2 3 2 3 1 3 1 5 3 1 2 1 3 2 3

Sample Output

3 4 1 样例解释 从1号节点直接走到至2号节点,距离为3。 从1号节点经2号节点走到至3号节点,距离为4。 从2号节点直接走到至3号节点,距离为1。

Hint

数据范围及约定

Source

from LH&LYT

Hide Information »

 

Case Time Limit: 2000 ms
Memory Limit: 256536 KB
Case score: 10
Comparison: Traditional
Level: 4
 Congratulation !
Users Submitted: 9
Users Solved: 8
Total Submits: 17
Accepted: 8
Time Out: 3
Wrong Answer: 1
Runtime Error: 3
Compile Error: 2
Submit         Status          Discuss
 
 
 Mark

 

 
 
题解:由于m只比n大一点,我们可以先找个树出来,然后两点之间最短路要么经过树上,要么经过非树边
所以我们对非树边每个点跑个spfa,然后询问时每个依次暴力比较,因为只有21,所以不会T
code:
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<queue>
  4 #include<cstring>
  5 #include<algorithm>
  6 #define N 300006
  7 using namespace std;
  8 struct node{
  9     long long u,v,w;
 10 }e[N],e1[N],a[N],temp[N];
 11 long long cnt1,first1[N],nxt1[N];
 12 void add1(long long u,long long v,long long w){
 13     e1[++cnt1].u=u;
 14     e1[cnt1].v=v;
 15     e1[cnt1].w=w;
 16     nxt1[cnt1]=first1[u];
 17     first1[u]=cnt1;
 18 }
 19 long long first[N],nxt[N],cnt;
 20 void add(long long u,long long v,long long w){
 21     e[++cnt].u=u;
 22     e[cnt].v=v;
 23     e[cnt].w=w;
 24     nxt[cnt]=first[u];
 25     first[u]=cnt;
 26 }
 27 long long fa[N];
 28 long long find(long long x){
 29     if(x!=fa[x])return fa[x]=find(fa[x]);
 30     return fa[x];
 31 }
 32 void merge(long long x,long long y){
 33     long long f1=find(x),f2=find(y);
 34     if(f1!=f2){
 35         fa[f1]=f2;
 36     }
 37 }
 38 long long dep[N],f[N][32];
 39 long long lca(long long x,long long y){
 40     if(dep[y]>dep[x])swap(x,y);
 41     for(long long i=30;i>=0;i--){
 42         if(dep[f[x][i]]>=dep[y])
 43         x=f[x][i];
 44         if(x==y)return x;
 45     }
 46     for(long long i=30;i>=0;i--){
 47         if(f[x][i]==f[y][i])continue;
 48         x=f[x][i],y=f[y][i];
 49     }
 50     return f[x][0];
 51 }
 52 long long check[N],n,m,cnt_;
 53 void kruskal(){
 54     long long cnt_=0;
 55     for(long long i=1;i<=m;i++){
 56         long long u=a[i].u,v=a[i].v,w=a[i].w;
 57         if(find(u)!=find(v)){
 58             merge(u,v);
 59             check[i]=1;
 60             add1(u,v,w);
 61             add1(v,u,w);
 62             cnt_++;
 63             if(cnt_==n-1)return;
 64         }
 65     }
 66 }
 67 long long vis[N],dis[50][N];
 68 void spfa(long long s,long long now){
 69     queue<long long>q;
 70     memset(vis,0,sizeof vis);
 71     dis[s][now]=0;
 72     vis[now]=1;
 73     q.push(now);
 74     while(!q.empty()){
 75         long long u=q.front();
 76         q.pop();
 77         vis[u]=0;
 78         for(long long i=first[u];i;i=nxt[i]){
 79             long long v=e[i].v;
 80             if(dis[s][v]>dis[s][u]+e[i].w){
 81                 dis[s][v]=dis[s][u]+e[i].w;
 82                 if(!vis[v]){
 83                     vis[v]=1;
 84                     q.push(v);
 85                 }
 86             }
 87         }
 88     }
 89 }
 90 bool cmp(const node &a,const node &b){
 91     return a.w<b.w; 
 92 }
 93 long long distree[N];
 94 void dfs(long long x){
 95     for(long long i=first1[x];i;i=nxt1[i]){
 96         long long v=e1[i].v;
 97         if(v==f[x][0])continue;
 98         f[v][0]=x;
 99         dep[v]=dep[x]+1;
100         distree[v]=distree[x]+e1[i].w;
101         dfs(v);
102     }
103 }
104 long long tot,tot_point,dian[N];
105 long long read(){
106     long long x=0,f=1;
107     char c=getchar();
108     while(!isdigit(c)){
109         if(c=='-')f=-1;
110         c=getchar();
111     }
112     while(isdigit(c)){
113         x=(x<<3)+(x<<1)+c-'0';
114         c=getchar();
115     }
116     return x*f;
117 }
118 int main(){
119 //    freopen("game.out","w",stdout);
120     memset(dis,0x3f3f3f3f,sizeof dis);
121     n=read(),m=read();
122     for(long long i=1;i<=n;i++)fa[i]=i;
123     for(long long i=1;i<=m;i++){
124         a[i].u=read(),a[i].v=read(),a[i].w=read();
125         add(a[i].u,a[i].v,a[i].w);
126         add(a[i].v,a[i].u,a[i].w);
127     }
128     sort(a+1,a+m+1,cmp);
129     kruskal();
130     for(long long i=1;i<=m;i++){
131         if(check[i])continue;
132 //        cout<<a[i].u<<" ||| "<<a[i].v<<" ||| "<<a[i].w<<'\n';
133         temp[++tot].u=a[i].u;
134         temp[tot].v=a[i].v;
135         temp[tot].w=a[i].w;
136         dian[++tot_point]=a[i].u;
137         dian[++tot_point]=a[i].v;
138         spfa(tot_point-1,a[i].u);
139         spfa(tot_point,a[i].v);
140     }
141     //cout<<dian[3]<<" &&&& "<<dis[3][2]<<'\n';
142     f[1][0]=1;
143     dfs(1);
144 //    for(int i=1;i<=tot_point;i++){
145 //        for(int j=1;j<=n;j++){
146 //            cout<<"st->"<<dian[i]<<" ed->"<<j<<" dist->"<<dis[i][j]<<'\n';
147 //        }
148 //    }
149 //    for(int i=1;i<=n;i++){
150 //        cout<<"father->"<<f[i][0]<<" dis->"<<distree[i]<<" dep->"<<dep[i]<<endl;
151 //    }
152     for(long long i=1;i<=30;i++){
153         for(long long j=1;j<=n;j++){
154             f[j][i]=f[f[j][i-1]][i-1];
155         }
156     }
157 //    cout<<"lca->"<<lca(5,2)<<endl;
158 //    for(int i=1;i<=n;i++){
159 //        cout<<"father->"<<f[i][1]<<" dis->"<<distree[i]<<" dep->"<<dep[i]<<endl;
160 //    }
161     long long Q;
162     Q=read();//dp,数论,图论,数据结构高级算法 
163     while(Q--){
164         long long u,v;
165         u=read();v=read();
166         long long ans=distree[u]+distree[v]-2*distree[lca(u,v)];
167         for(long long i=1;i<=tot;i++){
168             ans=min(ans,dis[i*2-1][u]+dis[i*2][v]+temp[i].w);
169             ans=min(ans,dis[i*2-1][v]+dis[i*2][u]+temp[i].w);
170         }
171         cout<<ans<<'\n';
172     }
173     return 0;
174 }
175 /*
176 5 6
177 1 2 1
178 2 3 2
179 3 4 3
180 4 5 4
181 5 1 5
182 1 3 1
183 5
184 1 5
185 2 4
186 3 4
187 2 1
188 3 5
189 */

over

posted @ 2018-10-15 21:02  saionjisekai  阅读(65)  评论(0编辑  收藏  举报