游记分享

博客班级 https://edu.cnblogs.com/campus/zjcsxy/SE2020
作业要求 https://edu.cnblogs.com/campus/zjcsxy/SE2020/homework/11334
作业目标 1. 编写一个小程序,可以全新编写,也可以学习别人的小程序进行修改 2. 熟悉git代码管理流程,将源代码上传到到github 3. 在博客园班级中写一篇相应的博文
作业源代码 git@github.com:wfs2018/software-engineering.git
学号 31801131 翁芳胜
院系 浙大城市学院计算分院

项目描述

本项目的灵感来自于小红书和大众点评,年轻人常常在这些平台上发布吃喝玩乐的心得和推荐。假期是时候想出去游玩却难以选择游玩地点。于是想到做一个旅游日记共享平台,可以看他人的游玩经历和心得。从而选择自己喜欢的游玩地点。由于是第一次做小程序,没有相关知识和经验,本项目只完成了首页游记展示,发布,收藏和喜欢的简单前端搭建,后续随着进一步的学习会完善相关功能。

参考:https://github.com/harveyqing/BearDiary.git

项目页面展示







{
"pages": [
"pages/list/list",
"pages/mine/mine",
"pages/new/new",
"pages/entry/entry"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#5566aa",
"navigationBarTitleText": "游记分享",
"navigationBarTextStyle": "white",
"backgroundColor": "#eceff4"
},
"tabBar": {
"color": "#858585",
"selectedColor": "#39b5de",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/list/list",
"iconPath": "images/icons/mark.png",
"selectedIconPath": "images/icons/markHL.png",
"text": "印记"
},
{
"pagePath": "pages/mine/mine",
"iconPath": "images/icons/mine.png",
"selectedIconPath": "images/icons/mineHL.png",
"text": "我的"
}
]
},
"debug": true,
"sitemapLocation": "sitemap.json"
}

各页面代码

首页

wxml文件

<!-- dairy.wxml -->

<template name="content-item">
<block wx:if="{{content.type == 'TEXT'}}">
<view style="margin-top:30rpx">
<text wx:if="{{content.type == 'TEXT'}}" class="text">{{content.content}}</text>
</view>
</block>
<block wx:if="{{content.type == 'IMAGE'}}">
<image class="media" mode="aspectFill" src="{{content.content}}" bindtap="enterPreviewMode" data-src="{{content.content}}"></image>
<view style="margin-top: 10rpx">{{content.description}}</view>
</block>
<block wx:if="{{content.type == 'VIDEO'}}">
<video class="media" src="{{content.content}}"></video>
<view style="margin-top: 10rpx">{{content.description}}</view>
</block>
<template is="content-footer" data="{{content}}"></template>
</template> <!-- 正文footer -->
<template name="content-footer">
<view class="footer">
<view class="left">
<image mode="aspectFit" src="../../images/icons/poi.png"></image>
<text style="margin-left:10rpx;">{{content.poi.name}}</text>
</view>
<view class="right">
<image mode="aspectFit" src="../../images/icons/comment.png"></image>
<view>{{content.commentNum}}</view>
</view>
<view class="right">
<image mode="aspectFit" src="../../images/icons/like.png"></image>
<view>{{content.likeNum}}</view>
</view>
</view>
</template> <view class="container">
<view class="header" style="#ffffff">
<!--顶部固定工具栏-->
<view class="toolbar">
<image class="item" mode="aspectFit" wx:for="{{toolbar}}" src="{{item}}"></image>
</view> <!--meta信息区-->
<view class="title">
<image class="avatar" mode="aspectFit" src="{{diary.meta.avatar}}"> </image>
<view class="desc">
<view class="item">{{diary.meta.title}}</view>
<view class="item">{{diary.meta.meta}}</view>
</view>
</view>
</view> <!--正文-->
<view wx:for="{{diary.list}}" wx:for-item="content" class="content">
<template is="content-item" data="{{content}}"></template>
</view> <view id="footer">
<view class="container">
<view class="item" style="font-size:50rpx;">
<view style="display:inline-block">游记</view>
<view style="display:inline-block;margin-left:10rpx;color:#2EA1CA;">分享</view>
</view>
<view class="item" style="font-size:24rpx;color:gray">分享旅程,分享心情</view>
</view>
</view>
</view> <!-- 预览模式 -->
<swiper class="swiper-container" duration="400" current="{{previewIndex}}" bindtap="leavePreviewMode" style="display:{{previewMode ? 'block' : 'none'}};">
<block wx:for="{{mediaList}}" wx:for-item="media">
<swiper-item>
<image src="{{media.content}}" mode="aspectFit"></image>
</swiper-item>
</block>
</swiper>

Js文件

// entry.js

const toolbar = [
'../../images/nav/download.png', '../../images/nav/fav.png',
'../../images/nav/share.png', '../../images/nav/comment.png',
];
const app = getApp(); Page({
data: {
// 当前日志
diary: undefined, // 右上角工具栏
toolbar: toolbar, // 图片预览
previewMode: false, // 当前预览
previewIndex: 0, // 内容列表
mediaList: [],
}, // 加载日记
getDiary(params) {
console.log("Loading diary data...", params); var id = params["id"], diary;
app.getDiaryList(list => {
if (typeof id === 'undefined') {
diary = list[0];
} else {
diary = list[id];
}
}); this.setData({
diary: diary,
});
}, // 过滤出预览图片列表
getMediaList() {
if (typeof this.data.diary !== 'undefined' &&
this.data.diary.list.length) {
this.setData({
mediaList: this.data.diary.list.filter(
content => content.type === 'IMAGE'),
})
}
}, // 进入预览
enterPreviewMode(event) {
let url = event.target.dataset.src;
let urls = this.data.mediaList.map(media => media.content);
let previewIndex = urls.indexOf(url); this.setData({previewMode: true, previewIndex});
}, // 退出预览
leavePreviewMode() {
this.setData({previewMode: false, previewIndex: 0});
}, onLoad: function(params) {
this.getDiary(params);
this.getMediaList();
}, onHide: function() {
},
})

我的页面

Wxml文件

<!--mine.wxml-->

<template name="tab1">
<view>
</view>
</template> <template name="tab2">
<view>
</view>
</template> <template name="tab3">
<view>
</view>
</template> <template name="tab4">
<view>
</view>
</template> <view>
<!--全屏对话框-->
<view class="modal" style="{{modalShowStyle}}">
<view class="dialog">
<view class="modal-item" style="display:flex;justify-content:center;align-items:center;">
请输入日记标题
</view>
<view class="modal-item" style="margin:0 auto;width:90%;">
<input type="text" bindinput="titleInput" style="background-color:white;border-radius:2px;" value="{{diaryTitle}}" placeholder="请输入日记标题"></input>
</view>
<view class="modal-button" style="width:100%">
<view style="color:green;border-right:1px solid #E5E7ED;" bindtap="touchAddNew">确定</view>
<view bindtap="touchCancel">取消</view>
</view>
</view>
</view> <view class="header">
<view class="profile">
<image class="avatar" mode="aspectFit" src="{{userInfo.avatar}}"></image>
<view class="description">
<view class="item">
<view style="margin-right:5px">{{userInfo.nickname}}</view>
<view>{{userInfo.sex}}</view>
</view>
<view class="item">{{userInfo.meta}}</view>
</view>
<image class="add" mode="aspectFill" src="../../images/icons/add.png" bindtap="touchAdd"></image>
</view> <view class="tablist">
<view wx:for="{{tabs}}" wx:for-index="idx" class="tab" bindtap="touchTab" style="{{item.extraStyle}}" id="{{idx}}">
<view class="content" style="color:{{highLightIndex == idx ? '#54BFE2' : ''}};">
<image class="image" mode="aspectFit" src="{{highLightIndex == idx ? item.iconActive : item.icon}}"></image>
<view style="margin-top:2px;">{{item.title}}</view>
</view>
</view>
</view>
</view> <template is="{{currentTab}}"></template>
</view>

Js

// mine.js

var iconPath = "../../images/icons/"
var tabs = [
{
"icon": iconPath + "mark.png",
"iconActive": iconPath + "markHL.png",
"title": "日记",
"extraStyle": "",
},
{
"icon": iconPath + "collect.png",
"iconActive": iconPath + "collectHL.png",
"title": "收藏",
"extraStyle": "",
},
{
"icon": iconPath + "like.png",
"iconActive": iconPath + "likeHL.png",
"title": "喜欢",
"extraStyle": "",
},
{
"icon": iconPath + "more.png",
"iconActive": iconPath + "moreHL.png",
"title": "更多",
"extraStyle": "border:none;",
},
]
var userInfo = {
avatar: "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3049066004,1582117064&fm=26&gp=0.jpg",
nickname: "wfs",
sex: "♂", // 0, male; 1, female
meta: '10篇日记',
} Page({ // data
data: {
// 展示的tab标签
tabs: tabs, // 当前选中的标签
currentTab: "tab1", // 高亮的标签索引
highLightIndex: "0", // 模态对话框样式
modalShowStyle: "", // 待新建的日记标题
diaryTitle: "", // TODO 用户信息
userInfo: userInfo,
}, // 隐藏模态框
hideModal() {
this.setData({modalShowStyle: ""});
}, // 清除日记标题
clearTitle() {
this.setData({diaryTitle: ""});
}, onShow: function() {
this.hideModal();
this.clearTitle();
}, // 点击tab项事件
touchTab: function(event){
var tabIndex = parseInt(event.currentTarget.id);
var template = "tab" + (tabIndex + 1).toString(); this.setData({
currentTab: template,
highLightIndex: tabIndex.toString()
}
);
}, // 新建日记事件
touchAdd: function (event) {
this.setData({
modalShowStyle: "opacity:1;pointer-events:auto;"
})
}, // 新建日记
touchAddNew: function(event) {
this.hideModal(); wx.navigateTo({
url: "../new/new?title=" + this.data.diaryTitle,
});
}, // 取消标题输入
touchCancel: function(event) {
this.hideModal();
this.clearTitle();
}, // 标题输入事件
titleInput: function(event) {
this.setData({
diaryTitle: event.detail.value,
})
}
})

新建日记页面

<!--new.wxml-->

<template name="common">
<scroll-view class="container" scroll-y="true">
<view class="common-container">
<view class="item-group" wx:for="{{layoutList}}" wx:for-item="group">
<block wx:for="{{group}}" wx:for-item="item">
<block wx:if="{{item.type == 'TEXT'}}">
<view class="album-item content-text">
<view>{{item.content}}</view>
</view>
</block>
<block wx:elif="{{item.type == 'IMAGE'}}">
<image src="{{item.content}}" class="album-item" mode="aspectFill"></image>
</block>
<block wx:elif="{{item.type == 'VIDEO'}}">
<video class="album-item" src="{{item.content}}"></video>
</block>
</block>
</view>
</view>
</scroll-view> <view class="tabbar" style="display:{{showTab ? 'flex' : 'none'}};">
<view class="item" bindtap="inputTouch">
<image class="icon" mode="aspectFit" src="../../images/tabbar/text.png"></image>
</view>
<view class="item" bindtap="mediaTouch">
<image class="icon" mode="aspectFit" src="../../images/tabbar/image.png"></image>
</view>
<view class="item">
<image class="icon" mode="aspectFit" src="../../images/tabbar/more.png"></image>
</view>
</view> <action-sheet hidden="{{mediaActionSheetHidden}}" bindchange="mediaActionSheetChange">
<block wx:for-items="{{mediaActionSheetItems}}" wx:for-index="id">
<action-sheet-item class="action-item" bindtap="{{mediaActionSheetBinds[id]}}">
{{item}}
</action-sheet-item>
</block>
<action-sheet-cancel class='action-cacel'>取消</action-sheet-cancel>
</action-sheet>
</template> <template name="inputText">
<view class="input-container">
<view style="height:47rpx" wx:for="{{inputStatus.lines}}" wx:for-index="idx">
<input type="text" data-index="{{idx}}" placeholder="" bindinput="textInput" bindchange="textInputChange" value="{{item}}" auto-focus="{{idx == inputStatus.row ? true : false}}" bindfocus="focusInput"/>
</view>
</view>
<view class="tabbar">
<view class="item" style="width:50%" bindtap="inputCancel">
<image class="icon" mode="aspectFit" src="../../images/tabbar/cancel.png"></image>
</view>
<view class="item" style="width:50%" bindtap="inputDone">
<image class="icon" mode="aspectFit" src="../../images/tabbar/ok.png"></image>
</view>
</view>
</template> <view style="width:100%;height:100%">
<block wx:if="{{showMode == 'common'}}">
<template is="{{showMode}}" data="{{showTab: showTab, mediaActionSheetHidden: mediaActionSheetHidden, mediaActionSheetItems: mediaActionSheetItems, mediaActionSheetBinds: mediaActionSheetBinds, layoutList: layoutList}}"></template>
</block>
<block wx:if="{{showMode == 'inputText'}}">
<template is="{{showMode}}" data="{{inputStatus}}"></template>
</block>
<loading hidden="{{!showLoading}}" bindchange="hideLoading">
{{loadingMessage}}
</loading>
</view>

Js

// new.js
// TODO 并不是所有非中文字符宽度都为中文字符宽度一半,需特殊处理
// TODO 由于文本框聚焦存在bug,故编辑模式待实现 const input = require('../../utils/input');
const config = require('../../config');
const geo = require('../../services/geo');
const util = require('../../utils/util'); const RESOLUTION = 750; // 微信规定屏幕宽度为750rpx
const MARGIN = 10; // 写字面板左右margin
const ROW_CHARS = Math.floor((RESOLUTION - 2 * MARGIN) / config.input.charWidth);
const MAX_CHAR = 1000; // 最多输1000字符 // 内容布局
const layoutColumnSize = 3; // 日记内容类型
const TEXT = 'TEXT';
const IMAGE = 'IMAGE';
const VIDEO = 'VIDEO'; const mediaActionSheetItems = ['拍照', '选择照片', '选择视频'];
const mediaActionSheetBinds = ['chooseImage', 'chooseImage', 'chooseVideo']; var app = getApp(); Page({ data: {
// 日记对象
diary: {
meta: {},
list: [],
}, // 日记内容布局列表(2x2矩阵)
layoutList: [], // 是否显示loading
showLoading: false, // loading提示语
loadingMessage: '', // 页面所处模式
showMode: 'common', // 输入框状态对象
inputStatus: {
row: 0,
column: 0,
lines: [''],
mode: 'INPUT',
auto: false, // 是否有自动换行
}, // 当前位置信息
poi: null, // 点击`图片`tab的action-sheet
mediaActionSheetHidden: true, // 多媒体文件插入action-sheet
mediaActionSheetItems: mediaActionSheetItems, // 多媒体文件插入项点击事件
mediaActionSheetBinds: mediaActionSheetBinds, // 是否显示底部tab栏
showTab: true,
}, // 显示底部tab
showTab() {
this.setData({showTab: true});
}, // 隐藏底部tab
hideTab() {
this.setData({showTab: false});
}, // 显示loading提示
showLoading(loadingMessage) {
this.setData({showLoading: true, loadingMessage});
}, // 隐藏loading提示
hideLoading() {
this.setData({showLoading: false, loadingMessage: ''});
}, // 数据初始化
init() {
this.getPoi();
this.setMeta();
}, // 设置日记数据
setDiary(diary) {
let layout = util.listToMatrix(diary.list, layoutColumnSize);
this.setData({diary: diary, layoutList: layout});
this.saveDiary(diary);
}, // 保存日记
// TODO sync to server
saveDiary(diary) {
const key = config.storage.diaryListKey; app.getLocalDiaries(diaries => {
diaries[diary.meta.title] = diary;
wx.setStorage({key: key, data: diaries});
})
}, // 页面初始化
onLoad: function(options) {
if (options) {
let title = options.title;
if (title) {this.setData({
'diary.meta.title': title,
'diary.meta.create_time': util.formatTime(new Date()),
'diary.meta.cover': ''
});}
} this.init();
}, // 页面渲染完成
onReady: function(){
wx.setNavigationBarTitle({title: '编辑日记'});
}, onShow:function(){
// 页面显示
}, onHide:function(){
// 页面隐藏
}, onUnload:function(){
// 页面关闭
console.log('页面跳转中...');
}, // 清除正在输入文本
clearInput() {
this.setData({inputStatus: {
row: 0,
common: 0,
lines: [''],
mode: 'INPUT',
auto: false,
}});
}, // 结束文本输入
inputDone() {
let text = this.data.inputStatus.lines.join('\n');
let diary = this.data.diary; if (text) {
diary.list.push(this.makeContent(TEXT, text, ''));
this.setDiary(diary);
} this.inputCancel();
}, // 进入文本编辑模式
inputTouch(event) {
this.setData({showMode: 'inputText'});
}, // 取消文本编辑
inputCancel() {
this.setData({showMode: 'common'});
this.clearInput();
}, // 文本输入
textInput(event) {
console.log(event);
let context = event.detail; // 输入模式
if (this.data.inputStatus.mode === 'INPUT') {
if (context.value.length != context.cursor) {
console.log('用户输入中...');
} else {
let text = context.value;
let len = input.strlen(text);
let lines = this.data.inputStatus.lines;
let row = this.data.inputStatus.row;
let [extra, extra_index] = [[['']], 0];
let hasNewLine = false;
console.log('当前文本长度: ' + len); // 当前输入长度超过规定长度
if (len >= ROW_CHARS) {
// TODO 此处方案不完善
// 一次输入最好不超过两行
hasNewLine = true;
while (input.strlen(text) > ROW_CHARS) {
let last = text[text.length - 1]; if (input.strlen(extra[extra_index] + last) > ROW_CHARS) {
extra_index += 1;
extra[extra_index] = [''];
} extra[extra_index].unshift(last);
text = text.slice(0, -1);
}
} lines[lines.length - 1] = text;
if (hasNewLine) {
extra.reverse().forEach((element, index, array) => {
lines.push(element.join(''));
row += 1;
});
} let inputStatus = {
lines: lines,
row: row,
mode: 'INPUT',
auto: true, // // 自动换行的则处于输入模式
};
列表
wxml <scroll-view scroll-y="true">
<view wx:for="{{diaries}}" wx:for-index="idx" class="item-container" bindtap="showDetail" id="{{idx}}">
<image mode="aspectFit" src="{{item.meta.cover}}" class="cover"></image>
<view class="desc">
<view class="left">
<view style="font-size:32rpx;margin:10rpx 0;">{{item.meta.title}}</view>
<view style="font-size:24rpx;color:darkgray">{{item.meta.meta}}</view>
</view>
<view class="right">
<image mode="aspectFit" src="{{item.meta.avatar}}"></image>
<text style="font-size:24rpx;margin-top:10rpx;color:darkgray">{{item.meta.nickName}}</text>
</view>
</view>
</view>
</scroll-view>

JS

const config = require("../../config");

var app = getApp();

Page({

  data: {
// 日记列表
// TODO 从server端拉取
diaries: null, // 是否显示loading
showLoading: false, // loading提示语
loadingMessage: '',
}, /**
* 生命周期函数--监听页面加载
*/
onLoad() {
this.getDiaries();
}, /**
* 获取日记列表
*/
getDiaries() {
var that = this;
app.getDiaryList(list => {
that.setData({diaries: list});
})
}, // 查看详情
showDetail(event) {
wx.navigateTo({
url: '../entry/entry?id=' + event.currentTarget.id,
});
}
})

总结

这是第一次编写小程序,刚刚听到作业的时候很震惊一周要做一个小程序。从头开始学习html,css知识的同时,去参考完整的demo。一句一句的理解,调试。几天下来对小程序的结构有了了解。在做小程序的时候,也遇到了一些困难,在搜素引擎和同学们的帮助下也都解决了。虽然最后做的很粗糙,但是在这个过程中,基本上完成了小程序的入门,也知道了怎么去解决遇到的问题。这次的作业也让我明白,在开发方面还有很多需要学习的知识。需要更加努力

微信小程序-游记分享(无后台)的更多相关文章

  1. mpvue开发微信小程序,分享按钮报错:`Cannot read property 'apply' of null`

    用mpvue开发微信小程序,分享按钮报错:Cannot read property 'apply' of null onShareAppMessage 是于微信小程序Pages的生命周期钩子,顾这个方 ...

  2. 微信小程序绘制分享图

    微信小程序绘制分享图例子: demo下载地址:https://gitee.com/v-Xie/wxCanvasShar 大致代码会再以下说明 实际开发项目: 基础知识点: 了解canvas基础知识 w ...

  3. (一)校园信息通微信小程序从前端到后台整和笔记

    前段时间接触了微信小程序,现在回过头来做一些笔记. 先上效果图 后台数据管理界面(PHP) 校园信息通微信小程序前端界面 下面先简单的说一下怎样部署一个微信小程序 首先是前端 微信小程序有它专门的开发 ...

  4. 微信小程序-实现分享(带参数)

    微信小程序分享功能的实现方法有两种: 第一种 在page.js中实现onShareAppMessage,便可在小程序右上角选择分享该页面 onShareAppMessage: function () ...

  5. (一)微信小程序之模拟调用后台接口踩过的坑

    如下图标记的三个点 在调试过程中出现问题,特此记录. 1. 之前在浏览器测试接口习惯省略 http:// ,是因为浏览器默认有一个检测,在你输入的网址前面加http://,如果有就不加. 然而在微信小 ...

  6. 微信小程序,请求php后台返回json数据多出隐藏字符问题

    这几天在做一个微信小程序注册登录页面的时候碰到一个问题,就是使用wx.request api的时候success中返回的JSON数据前面会多出空白字符,后面网上查了一下是说php bom头问题(详细介 ...

  7. 微信小程序商城 带java后台源码

    微信小程序商城(Java版) 演示地址 账号:admin 密码:admin 小程序体验码: 技术选型 1 后端使用技术 1.1 springframework4.3.7.RELEASE 1.2 myb ...

  8. 微信小程序全局设置分享内容

    微信小程序每个页面都可以在onShareAppMessage中设置分享内容,如果想要全局设置成一样的分享内容如何设置呢? 在app.js中新增以下方法: //重写分享方法 overShare: fun ...

  9. 微信小程序之分享功能

    说到分享 大家都会想到手机右上角点击不就分享了么?对的没错,那样是分享转发的是小程序  而不是指定的某个页面,所以自己动手丰衣足食,自己写一个转发功能被, 其实也没那么可怕,主要参考的是微信小程序AP ...

随机推荐

  1. RabbitMQ小记(一)

    1.了解消息中间件 消息中间件,Message Queue Middleware,简称MQ,又称消息对列或消息对列中间件,利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式 ...

  2. Centos-yum软件包安装-yum

    yum 自动安装相关软件依赖,可以同时配置多个yum源,初始启动yum时候首先会缓存资源包到 /var/cache/yum目录下 yum确认 -y yum安装和卸载 install 安装,自动安装软件 ...

  3. Effective C++ 读书笔记 名博客

    https://www.cnblogs.com/harlanc/tag/effective%20c%2B%2B/default.html?page=3

  4. 关于C++的右值引用的一些看法

    简介 关于C++中的右值引用的详细可以看这一批博文<从4行代码看右值引用>.那一篇博文详细结合四行简单的代码详细介绍了右值引用的使用方法和一些场景,非常实用. 而本篇博文主要介绍一下我在学 ...

  5. Linux系统编程 —时序竞态

    时序竞态 什么是时序竞态?将同一个程序执行两次,正常情况下,前后两次执行得到的结果应该是一样的.但由于系统资源竞争的原因,前后两次执行的结果有可能得到不一样的结果,这个现象就是时序竞态. pause函 ...

  6. [Angular JS教程] HeroService: getHeroes failed: undefined 问题解决方法

    最近在学习入门Angular JS,学习资源是https://angular.cn/tutorial, 在学习到 "https://angular.cn/tutorial/toh-pt6模拟 ...

  7. Hyper-V Server + Windows Admin Center

    2020年的十一黄金周是双节,偶然间得知再出现双节可能要几十年之后了,很可惜我并没有出去游玩的打算.所以假期没什么事,就来研究下Hyper Server + Windows Admin Center. ...

  8. C++ 中explicit的作用

    转载:https://www.cnblogs.com/diligenceday/p/5781408.html C++ 中explicit的作用   explicit作用: 在C++中,explicit ...

  9. TCP/IP 寻址

    原文:TCP/IP 寻址 第一节:TCP/IP 简介 第二节:TCP/IP 寻址 第三节:TCP/IP 协议 第四节:TCP/IP 邮件 TCP/IP 使用 32 个比特(bit)或者 4 个 0 到 ...

  10. [WC 2011]最大Xor和路径

    题目大意: 给你一张n个点,m条边的无向图,每条边都有一个权值,求:1到n的路径权值和的最大值. 题解: 任意一条路径都能够由一条简单路径(任意一条),在接上若干个环构成(如果不与这条简单路径相连就走 ...