BZOJ5056 OI游戏[最短路树]

本文分享了一道被作者认为是有生以来在BZOJ上遇到的最简单的题目,其难度甚至低于A+B问题。文章中包含了题目的代码实现,使用了包括优先队列在内的多种数据结构和算法,如矩阵树定理,尽管作者提到这可能不是最优解法。代码中还展示了如何通过读取输入、建立图结构、进行图遍历以及计算结果来解决这个问题。
摘要由CSDN通过智能技术生成

有生以来做过的bzoj比A+B还简单的最水的题。(确信)

不解释。

UPD:据说这题正解应当是矩阵树定理?有生之年会补的。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #define dbg(x) cerr << #x << " = " << x <<endl
 8 using namespace std;
 9 typedef long long ll;
10 typedef double db;
11 typedef pair<int,int> pii;
12 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
13 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
14 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
15 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
16 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
17 template<typename T>inline T read(T&x){
18     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
19     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
20 }
21 const int N=60,P=1e9+7;
22 char s[N];
23 int n;
24 struct thxorz{int to,nxt,w;}G[10000];
25 int Head[N],tot;
26 inline void Addedge(int x,int y,int z){G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z;}
27 #define y G[j].to
28 int dis[N],cnt[N];
29 priority_queue<pii,vector<pii>,greater<pii> > q;
30 inline void stothxorz(){
31     memset(dis,0x3f,sizeof dis);q.push(make_pair(dis[1]=0,1));cnt[1]=1;
32     while(!q.empty()){
33         int x=q.top().second,d=q.top().first;q.pop();
34         if(dis[x]^d)continue;
35         for(register int j=Head[x];j;j=G[j].nxt)
36             if(dis[y]==d+G[j].w)++cnt[y];
37             else if(MIN(dis[y],d+G[j].w))cnt[y]=1,q.push(make_pair(dis[y],y));
38     }
39 }
40 #undef y
41 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
42     read(n);
43     for(register int i=1;i<=n;++i){
44         scanf("%s",s+1);
45         for(register int j=1;j<=n;++j)if(s[j]-'0')Addedge(i,j,s[j]-'0');
46     }
47     stothxorz();
48     int res=1;
49     for(register int i=1;i<=n;++i)res=res*1ll*cnt[i]%P;
50     printf("%d\n",res);
51     return 0;
52 }
View Code

 

转载于:https://www.cnblogs.com/saigyouji-yuyuko/p/11601406.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值