博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 2017女生赛04 (变形最短路)
阅读量:6003 次
发布时间:2019-06-20

本文共 4773 字,大约阅读时间需要 15 分钟。

Deleting Edges

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 263    Accepted Submission(s): 85


Problem Description
Little Q is crazy about graph theory, and now he creates a game about graphs and trees.
There is a bi-directional graph with 
n nodes, labeled from 0 to 
n1. Every edge has its length, which is a positive integer ranged from 1 to 9.
Now, Little Q wants to delete some edges (or delete nothing) in the graph to get a new graph, which satisfies the following requirements:
(1) The new graph is a tree with 
n1 edges.
(2) For every vertice 
v(0<v<n), the distance between 0 and 
v on the tree is equal to the length of shortest path from 0 to 
v in the original graph.
Little Q wonders the number of ways to delete edges to get such a satisfied graph. If there exists an edge between two nodes 
i and 
j, while in another graph there isn't such edge, then we regard the two graphs different.
Since the answer may be very large, please print the answer modulo 
109+7.
 

Input
The input contains several test cases, no more than 10 test cases.
In each test case, the first line contains an integer 
n(1n50), denoting the number of nodes in the graph.
In the following 
n lines, every line contains a string with 
n characters. These strings describes the adjacency matrix of the graph. Suppose the 
j-th number of the 
i-th line is 
c(0c9), if 
c is a positive integer, there is an edge between 
i and 
j with length of 
c, if 
c=0, then there isn't any edge between 
i and 
j.
The input data ensure that the 
i-th number of the 
i-th line is always 0, and the 
j-th number of the 
i-th line is always equal to the 
i-th number of the 
j-th line.
 

Output
For each test case, print a single line containing a single integer, denoting the answer modulo 
109+7.
 

Sample Input
 
2 01 10 4 0123 1012 2101 3210
 

Sample Output
 
1 6
 

Source
 

题意:

n个点,n*2-n条边,删除掉只剩下n-1条边,满住剩下的每个点在原图中都是最短路的存在。

分析:

dij队列优化需要vis,可以避免重复入队的情况,但是不加vis也不会无尽循环下去。

来自某个博客其他人的解法,其实也不需要跑完全图。

说入度乘积我更倾向于说成每个点走法的乘积。(5.15重温这句话发现这句话还是有问题的,到三点的还有一种画法)

dij算法就是求原点到各个点的最短路,也很贴合这道题的性质。那么不同走法之间会有影响吗?只有两个独立事件同时发生没有影响才能相乘。(有问题)

结果是没有影响。原题中说只要存在任意一条不同的边就是不同的图。

dij最短路的原理就是通过不同路来松弛。每种走法的组合一定可以存在一条异边。第三个点也是建立在前面点基础上通过扩展而来。

因为n为50,所以随便哪个最短路算法都能过吧:

正插邻接表加队列的确比反插好写多了。。。

#include 
#include
#include
#include
#include
#define mod 1000000007using namespace std;typedef long long ll;const int maxn = 100+10;const int INF = 0x3f3f3f3f;char ch[60][60];int cnt[maxn];struct node{ int x,d; node(){} node(int a,int b){x=a;d=b;} bool operator < (const node & a) const { return d > a.d; }};vector
eg[maxn];int dis[maxn];void Dijkstra(int s){ dis[s]=0; //用优先队列优化 priority_queue
q; q.push(node(s,dis[s])); while(!q.empty()) { node x=q.top();q.pop(); //最后一个点就可以跳出了 if(x.x==n-1) break; for(int i=0;i
x.d+y.d) { cnt[y.x] = 1; dis[y.x]=x.d+y.d; q.push(node(y.x,dis[y.x])); } else if(dis[y.x]==x.d+y.d) { cnt[y.x]++; } } }}int main(){// freopen("in.txt","r",stdin); int n; while(~scanf("%d",&n)) { for(int i=0;i<=n;i++) dis[i]=INF; memset(cnt,0,sizeof(cnt)); cnt[0]=1; for(int i=0;i<=n;i++) eg[i].clear(); for(int i=0;i
一开始超时的,不知道在哪里:

反正以后就用vector写了。。。。

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long ll;using namespace std;const int maxn = 60+10;const int INF = 0x3f3f3f3f;//int mp[maxn][maxn];int first[maxn];int cnt[maxn];int num,dis[100];char ch[60][60];int vis[60];#define mod 1000000007struct Node { int id; int val; }node;struct Edge { int id;//以此点为出边找边 int val; int next; }e[maxn];void add(int u,int v,int d) { //num边的编号 e[num].id = v; e[num].val = d; e[num].next = first[u]; first[u] = num; num++;}priority_queue
q;bool operator < (Node a,Node b) { return a.val > b.val;}int main() {// freopen("in.txt","r",stdin); int n,m; while(~scanf("%d",&n)) { memset(first,-1,sizeof(first)); memset(cnt,0,sizeof(cnt)); while(!q.empty()) q.pop(); for(int i=0;i
e[i].val+cur.val) { cnt[e[i].id] = 1; dis[e[i].id] = e[i].val+cur.val; node.id = e[i].id; node.val = dis[e[i].id]; q.push(node); } else if(dis[e[i].id] == e[i].val+cur.val) cnt[e[i].id]++; } } ll ans = 1LL; for(int i = 0; i < n; i++) { ans *= cnt[i]; ans %= mod; }// for(int i = 0; i <= n; i++) {// printf("初始点到%d点的距离为%d\n",i,dis[i]);// } printf("%d\n",ans); } return 0; }

转载于:https://www.cnblogs.com/zhangmingzhao/p/7256608.html

你可能感兴趣的文章
Visual Studio下使用jQuery的10个技巧
查看>>
数据库查询某个字段值的位数 语法
查看>>
WPF获取路径解读
查看>>
【实战HTML5与CSS3】用HTML5和CSS3制作页面(上)
查看>>
Android : 如何在WebView显示的页面中查找内容
查看>>
分享个人Vim型材
查看>>
配置算法(第4版)的Java编译环境
查看>>
本学习笔记TCP/IP传输协议
查看>>
荣耀10GT升级EMUI 9.0体验分享:这可能是最好用的手机操作系统
查看>>
ZStack基于华芯通打造ARM国产云平台 助力云上贵州多项应用
查看>>
200本“保护日记”记录黄山迎客松生长变化
查看>>
多方力量携手呵护“中华水塔”青海三江源
查看>>
从设计者的角度看 React
查看>>
《前端十年心路-我把一切告诉你》的书稿大纲&问题收集
查看>>
CSS居中总结大全
查看>>
Elasticsearch 参考指南(安装X-Pack)
查看>>
[LintCode] 604. Design Compressed String Iterator
查看>>
微信小程序黑客马拉松即将开始,来做最酷的 Mini Program Creators!
查看>>
JavaScript基础---函数
查看>>
前端每日实战:120# 视频演示如何用纯 CSS 创作锡纸撕开的文字效果
查看>>