1 #include<cstdio>
2 #include<iostream>
3 #include<cmath>
4 #include<vector>
5 #include<cstring>
6 #include<algorithm>
7 #define maxn 20005
8 #define maxm maxn<<2
9 #define mod 236897
10 using namespace std;
11 typedef long long int64;
12 char ch;
13 bool ok;
14 void read(int &x){
15 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch==‘-‘) ok=1;
16 for (x=0;isdigit(ch);x=x*10+ch-‘0‘,ch=getchar());
17 if (ok) x=-x;
18 }
19 int n,m,q,a,b,c;
20 int idx,dfn[maxn],low[maxn];
21 int top,cnt,bnm[maxn],tmp[maxn];
22 struct Stack{
23 int id,val;
24 }stack[maxn];
25 struct Point{
26 vector<int> bel,pos;
27 int siz;
28 void init(int a,int b){siz++,bel.push_back(a),pos.push_back(b);}
29 }point[maxn];
30 struct SCC{
31 vector<int> id,dis;
32 int siz,len,head;
33 void add(int v,int d){siz++,id.push_back(v),dis.push_back(d);}
34 int query(int a,int b){
35 int tmp=abs(dis[a]-dis[b]);
36 return min(tmp,len-tmp);
37 }
38 }scc[maxn];
39 int fa[maxn][15],dep[maxn],dis[maxn];
40 struct Hash{
41 int tot,key[mod],pre[maxn],ans[maxn];
42 int64 val[maxn];
43 void add(int a,int b,int id){
44 int64 t=1LL*a*maxn+b;
45 int u=t%mod;
46 for (int p=key[u];p;p=pre[p]) if (val[p]==t) return;
47 pre[++tot]=key[u],key[u]=tot,ans[tot]=id,val[tot]=t;
48 }
49 int find(int a,int b){
50 int64 t=1LL*a*maxn+b;
51 int u=t%mod;
52 for (int p=key[u];p;p=pre[p]) if (val[p]==t) return ans[p];
53 return -1;
54 }
55 }hash;
56 int num;
57 struct Edge{
58 int a,b,c;
59 }edge[maxm];
60 struct Graph{
61 int tot,now[maxn],son[maxm],pre[maxm],val[maxm];
62 void put(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
63 void add(int a,int b,int c){put(a,b,c),put(b,a,c);}
64 void dfs(int u,int fa,int va){
65 dfn[u]=low[u]=++idx,stack[++top]=(Stack){u,va};
66 for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
67 if (!dfn[v]) dfs(v,u,val[p]),low[u]=min(low[u],low[v]);
68 else if (v!=fa) tmp[u]=val[p],low[u]=min(low[u],dfn[v]);
69 if (dfn[u]==low[u]){
70 top--;
71 if (fa) bnm[u]++,bnm[fa]++,edge[++num]=(Edge){fa,u,va};
72 }
73 if (low[u]==dfn[fa]){
74 int v,va,d=0,id=0,first=stack[top].id; ++cnt;
75 do{
76 v=stack[top].id,va=stack[top].val,top--;
77 point[v].init(cnt,id++),scc[cnt].add(v,d),d+=va;
78 }while (v!=u);
79 point[fa].init(cnt,id++),scc[cnt].add(fa,d),scc[cnt].len=d+tmp[first];
80 }
81 }
82 void dfs1(int u){
83 for (int i=0;fa[u][i];i++) fa[u][i+1]=fa[fa[u][i]][i];
84 if (u>n){
85 int idx=u-n;
86 if (fa[u][0]) scc[idx].head=hash.find(fa[u][0],idx);
87 for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
88 if (v!=fa[u][0]){
89 fa[v][0]=u,dep[v]=dep[u]+1;
90 dis[v]=dis[u]+scc[idx].query(scc[idx].head,hash.find(v,idx)),dfs1(v);
91 }
92 }
93 else for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
94 if (v!=fa[u][0]) fa[v][0]=u,dep[v]=dep[u]+1,dis[v]=dis[u]+val[p],dfs1(v);
95 }
96 }G1,G2;
97 void swim(int &u,int h){for (int i=14;h;i--) if (h>=(1<<i)) h-=(1<<i),u=fa[u][i];}
98 int get_lca(int u,int v){
99 if (dep[u]<dep[v]) swap(u,v);
100 swim(u,dep[u]-dep[v]);
101 if (u==v) return u;
102 for (int i=14;i>=0;i--) if (fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
103 return fa[u][0];
104 }
105 int get(int u){
106 if (!point[u].siz) return u;
107 return point[u].bel[0]+n;
108 }
109 void query(int a,int b){
110 int ans=0;
111 int ta=get(a),tb=get(b);
112 int lca=get_lca(ta,tb);
113 if (tb==lca) swap(ta,tb),swap(a,b);
114 if (ta==lca){
115 if (tb==lca){
116 if (lca>n){
117 int ida=hash.find(a,lca-n),idb=hash.find(b,lca-n);
118 printf("%d\n",scc[lca-n].query(ida,idb));
119 }
120 else puts("0");
121 }
122 else{
123 if (tb>n) ans+=scc[tb-n].query(scc[tb-n].head,point[b].pos[0]),b=tb;
124 if (lca>n){
125 swim(tb,dep[tb]-dep[lca]-1);
126 int ida=hash.find(a,lca-n),idb=hash.find(tb,lca-n);
127 printf("%d\n",ans+dis[b]-dis[tb]+scc[lca-n].query(ida,idb));
128 }
129 else printf("%d\n",ans+dis[tb]-dis[lca]);
130 }
131 }
132 else{
133 if (ta>n) ans+=scc[ta-n].query(scc[ta-n].head,point[a].pos[0]),a=ta;
134 if (tb>n) ans+=scc[tb-n].query(scc[tb-n].head,point[b].pos[0]),b=tb;
135 if (lca>n){
136 swim(ta,dep[ta]-dep[lca]-1),swim(tb,dep[tb]-dep[lca]-1);
137 int ida=hash.find(ta,lca-n),idb=hash.find(tb,lca-n);
138 printf("%d\n",ans+dis[a]-dis[ta]+dis[b]-dis[tb]+scc[lca-n].query(ida,idb));
139 }
140 else printf("%d\n",ans+dis[a]+dis[b]-(dis[lca]<<1));
141 }
142 }
143 int main(){
144 read(n),read(m),read(q);
145 for (int i=1;i<=m;i++) read(a),read(b),read(c),G1.add(a,b,c);
146 for (int i=1;i<=n;i++) if (!dfn[i]) G1.dfs(i,0,0);
147 for (int i=1;i<=num;i++) G2.add(edge[i].a,edge[i].b,edge[i].c);
148 for (int u=1;u<=n;u++) if (bnm[u]+point[u].siz>=2)
149 for (int i=0;i<point[u].siz;i++) G2.add(u,n+point[u].bel[i],0);
150 for (int u=1;u<=n;u++) for (int i=0;i<point[u].siz;i++) hash.add(u,point[u].bel[i],point[u].pos[i]);
151 int root=cnt?n+1:1;
152 G2.dfs1(root);
153 while (q--) read(a),read(b),query(a,b);
154 return 0;
155 }