Wycieczki 线性代数
B. Wycieczki
題目描述
給定一張n個(gè)點(diǎn)m條邊的帶權(quán)有向圖,每條邊的邊權(quán)只可能是1,2,3中的一種。
將所有可能的路徑按路徑長度排序,請(qǐng)輸出第k小的路徑的長度,注意路徑不一定是簡(jiǎn)單路徑,即可以重復(fù)走同一個(gè)點(diǎn)。
輸入格式
第一行包含三個(gè)整數(shù)n,m,k(1<=n<=40,1<=m<=1000,1<=k<=10^18)。
接下來m行,每行三個(gè)整數(shù)u,v,c(1<=u,v<=n,u不等于v,1<=c<=3),表示從u出發(fā)有一條到v的單向邊,邊長為c。
可能有重邊。
輸出格式
包含一行一個(gè)正整數(shù),即第k短的路徑的長度,如果不存在,輸出-1。
樣例
樣例輸入
6 6 11 1 2 1 2 3 2 3 4 2 4 5 1 5 3 1 4 6 3樣例輸出
4數(shù)據(jù)范圍與提示
長度為1的路徑有1->2,5->3,4->5。
長度為2的路徑有2->3,3->4,4->5->3。
長度為3的路徑有4->6,1->2->3,3->4->5,5->3->4。
長度為4的路徑有5->3->4->5。
這道題時(shí)間跨度比較長了,主要是因?yàn)檫@道題賊難調(diào),稍有不慎就會(huì)WA,而且這道題的測(cè)試點(diǎn)賊多,多到會(huì)出現(xiàn)2分情況,所以真的是我的簽名說的,一杯茶一包紙,一份代碼調(diào)成X
其實(shí)這道題還算好像,而且有思維量,主要就是要把邊的矩陣拆點(diǎn),然后建邊,注意需點(diǎn),也就是整個(gè)矩陣會(huì)擴(kuò)大三倍;整個(gè)題其實(shí)就是二分(我打了一半,跑的實(shí)在是太慢了,所以換了一種方法)倍增,倍增就和求lca其實(shí)是一樣的,就是換成了矩陣,不知其他神犇是怎么打的,反正我是使用結(jié)構(gòu)體,但是要注意細(xì)節(jié),整個(gè)卡了一晚上,就是因?yàn)榫仃噦鲄]加取地址,加上就A了,有神犇知道為啥的就留言吧
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> using namespace std; #define LL long long #define re register #define F(i,a,b) for(LL i=a;i<=b;i++) LL n,m,u,v,d,t; long long s,k; bool flag; inline LL read() {re LL ss=0;char bb=getchar();while(bb<48||bb>57)bb=getchar();while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();return ss; } struct Martix {LL x[250][250];void init(){memset(x,0,sizeof(x));} }mul[125],tmp; Martix bg,base,now; void made(Martix &a,Martix &b,Martix &c) {flag=1;tmp.init();F(i,1,3*n+1)F(l,1,3*n+1){if(!a.x[i][l])continue;//debug(i);debug(l);F(j,1,3*n+1)tmp.x[i][j]=tmp.x[i][j]+a.x[i][l]*b.x[l][j];if(i==1&&tmp.x[i][3*n+1]>=k)flag=0; }c=tmp; } int main() {//freopen("cnm.txt","r",stdin);n=read(),m=read(),k=read();F(i,1,n){bg.x[1][i]=1;base.x[i][i+n]=1;base.x[i+n][i+2*n]=1;}while(m--){u=read(),v=read(),d=read();base.x[u+(d-1)*n][v]++;base.x[u+(d-1)*n][3*n+1]++;}base.x[3*n+1][3*n+1]=1;mul[0]=base;for(;t<=63;t++){ if(t)made(mul[t-1],mul[t-1],mul[t]);made(bg,mul[t],now);if(!flag||now.x[1][3*n+1]>=k){break;}}t--;if(t==63&&now.x[1][3*n+1]<k){puts("-1");return 0;}for(LL i=t;i>=0;i--){made(bg,mul[i],now);if(flag&&now.x[1][3*n+1]<k){s+=(1ll<<i);bg=now;}}printf("%lld\n",s+1); } hhhendl;
?
轉(zhuǎn)載于:https://www.cnblogs.com/hzoi-lsc/p/11209856.html
總結(jié)
以上是生活随笔為你收集整理的Wycieczki 线性代数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对HashMap对象的键值对内容进行排序
- 下一篇: 4-1 面向对象概述