l2-4网红打卡攻略
题意: 略。
思路: 按给定的序列模拟一下即可,如果某个点出现次数不为1,说明不符合条件,或者中间存在点不可达。忘了把不符合条件的情况设为INF,wa了半天。
时间复杂度: O(k*n)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 502;
#define int long long
const int INF = 1e12;
int n,m,k,T;
int a[N][N];
int ans[N];
int vis[N];
int tot;
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define mem(a,x) memset(a,x,sizeof(a))
bool check()
{
for(int i=1;i<=n;++i)
{
if(vis[i] != 1) return 0;
}
return 1;
}
void solve()
{
cin>>n>>m;
fir(i,0,n)
{
fir(j,0,n)
{
if(i==j) a[i][j] = 0;
else a[i][j] = INF;
}
}
for(int i=0;i<m;++i)
{
int x,y,z; cin>>x>>y>>z;
a[x][y] = a[y][x] = z;
}
cin>>k;
int idx = 1;
for(int t=1;t<=k;++t)
{
int num; cin>>num;
vector<int> vv;
vv.push_back(0);
for(int i=1;i<=n;++i) vis[i] = 0;
while(num--)
{
int x; cin>>x;
vis[x]++;
vv.push_back(x);
}
if(!check())
{
ans[t] = INF;
continue;
}
vv.push_back(0);
for(int i=1;i<vv.size();++i)
{
int l = vv[i-1];
int r = vv[i];
if(a[l][r] == INF)
{
// cout<<l<<" "<<r<<endl;
ans[t] = INF;
break;
}
else ans[t] += a[l][r];
}
if(ans[t] == INF) continue;
tot++;
if(ans[t] < ans[idx]) idx = t;
}
cout<<tot<<"\n";
cout<<idx<<" "<<ans[idx];
}
signed main(void)
{
solve();
return 0;
}
l3-1 那就别担心了。
题意: 给定n个点m条边的有向图,统计从st到ed的路径数有多少,并且判断从st开始的路径是否均以ed为终点。
思路: 记忆化搜索即可。如果不记忆化的话会T。终点的方案数默认为1,每个点的方案数是所有儿子的方案数之和。可以发现有很多点的方案数会重复计算,尤其是存在环的情况下。
时间复杂度: O(能过)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 522;
int n,m,k,T;
vector<int> va[N];
int ans = 0;
bool flag = 1;
int st,ed;
bool vis[N];
int f[N];
int dfs(int cur)
{
vis[cur] = 1;
if(f[cur]) return f[cur];
for(int i=0;i<va[cur].size();++i)
{
int j = va[cur][i];
f[cur] += dfs(j);
}
return f[cur];
}
void solve()
{
cin>>n>>m;
for(int i=0;i<m;++i)
{
int x,y; cin>>x>>y;
va[x].push_back(y);
}
cin>>st>>ed;
f[ed] = 1;
ans = dfs(st);
cout<<ans<<" ";
for(int i=1;i<=n;++i)
{
if(vis[i] && !f[i])
{
flag = 0;
}
}
if(flag) cout<<"Yes";
else cout<<"No";
}
signed main(void)
{
solve();
return 0;
}