。。。謹以此篇,紀念我的爆0(wa~~~~TT!!!)
A:
思路:想到了應該用dp做,想用數位。可是狀態轉移方程寫不出。。。
其實簡單的。。。d[i][j][k](//表示當前爲第i位,最後兩個是j,k)=can[l][j][k]*d[i-1][l][j],(l遍歷1,49);
代碼如下:
/*
*/
#define LOCAL
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
#include<vector>
#include<set>
using namespace std;
#define maxn 3000000
#define inf 40000000
#define LL long long
LL d[505][50][50];//現在第i位,i位爲j,i-1位爲k
int can[50][50][50];//不合法爲0,合法爲1
int mod=1e9+7;
int main()
{
#ifdef LOCAL
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
#endif
int n,q;
scanf("%d%d",&n,&q);
int a,b,c;
int i,j,k,u;
for(i=0;i<50;i++)
for(j=0;j<50;j++)
for(k=0;k<50;k++)
can[i][j][k]=1;
LL ans=0;
while(q--)
{
scanf("%d%d%d",&a,&b,&c);
can[a][b][c]=0;
can[a][c][b]=0;
can[b][a][c]=0;
can[b][c][a]=0;
can[c][a][b]=0;
can[c][b][a]=0;
}
for(int i=1;i<=2;i++)
for(int j=1;j<50;j++)
for(int k=1;k<50;k++)
d[i][j][k]=1;
for(int i=3;i<=n;i++)
{
for(int j=1;j<50;j++)
{
for(int k=1;k<50;k++)
{
for(int l=1;l<50;l++)
{
d[i][j][k]+=can[l][j][k]*d[i-1][l][j];
//最後兩位爲j,k時,倒數第三位l一定要滿足(l,j,k)合法,如果合法加上i-1位時,最後兩位是l,j的情況
d[i][j][k]%=mod;
}
}
}
}
for(int i=1;i<50;i++)
for(int j=1;j<50;j++)
ans+=d[n][i][j],ans%=mod;
cout<< ans%mod <<endl;
return 0;
}
C:從一個點出發,到終點,要遍歷每一條邊,並且每條邊只走一次,那麼主路(從起點到終點的路徑)只走一次,別的遍歷路徑都要走兩次;也就是要讓主路最長(樹的直徑);
代碼如下:
/*
c: 只有一條路徑可以只走一次,別的都要走兩次,所以選最長的路徑走一次,別的走兩次
ans=邊權和*2-直徑
*/
#define LOCAL
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
#include<vector>
#include<set>
using namespace std;
#define maxn 3000000
#define inf 40000000
#define LL long long
vector<int > G[maxn];//鄰接表
struct nod
{
int u,v,w;
}edge[maxn];//邊
bool vis[maxn];//判斷i點是否遍歷過
int maxx=0;//距1點最遠點
LL len;//當前長度
int len_max;
void dfs(int now)
{
int flag=0;//沒有出邊,即到達終點
int l=G[now].size();
for(int i=0;i<l;i++)
{
if(!vis[edge[G[now][i]].v])
{
vis[edge[G[now][i]].v]=1;
len+=edge[G[now][i]].w;
dfs(edge[G[now][i]].v);
vis[edge[G[now][i]].v]=0;
len-=edge[G[now][i]].w;
flag++;
}
}
if(flag==0)
{
if(len>len_max)
{
len_max=len;
maxx=now;
}
}
}
int main()
{
#ifdef LOCAL
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
#endif
int n,u,v,w;
LL ans=0;
cin>>n;
for(int i=0;i<n-1;i++)
{
cin>>edge[i].u>>edge[i].v>>edge[i].w;
edge[i+n].u=edge[i].v,edge[i+n].v=edge[i].u,edge[i+n].w=edge[i].w;
G[edge[i].u].push_back(i);//u的出邊
G[edge[i].v].push_back(i+n);//v的出邊
ans+=edge[i].w;
}
vis[1]=1;
dfs(1);
LL len1=len_max;
memset(vis,0,sizeof(vis));
vis[maxx]=1;
len=0;
len_max=0;
dfs(maxx);
LL len2=len_max;
//cout<<len1<<" "<<len2<<endl;
cout<<ans*2-len2<<endl;
return 0;
}