SCOJ 4427: Miss Zhao's Graph dp
4427: Miss Zhao's Graph
题目连接:
http://acm.scu.edu.cn/soj/problem.action?id=4427
Description
Mr Jiang gives Miss Zhao a problem about graphs. Unfortunately, she is not very good at graph theory.
However, she doesn't want to be looked down upon by Mr Jiang, who is always trying to laugh at her and call her "little fool".
Therefore, she turns to you for help.
There is a weighted directed graph which has n vertices and m edges. You should find a path with maximum number of edges, and the weight of each edge must be strictly greater than the weight of the provious one.
Print the number of edges in the path.
PS: There may be multiple edges with two nodes and self-loops in this graph.
Input
The first line of input is the number of test case.
Then for each case:
The first line contains two integers n,m(2<=n<=3*105;1<=m<=min(n*(n-1),3*105)).
Then, m lines follow. The i-th line contains three integers:
u,v,w(1<=u,v<=n;1<=w<=10^5) which indicates that there's a directed edge with weight w from vertex u to vertex v.
Constraints:
Print a single integer. The length of the path.
Output
For each case output the answer modulo 1000000007 in a single line.
Sample Input
2
3 3
1 2 1
2 3 2
3 1 3
6 7
1 2 1
3 2 5
2 4 2
2 5 2
2 6 9
5 4 3
4 3 4
Sample Output
3
6
Hint
题意
给你一个有向图,然后有边权
问你这个图内最长递增路径的长度是多少
题解:
对于每一条边,我们按照从小到大排序之后,然后直接跑dp就好了
dp[i]表示i点的最长路,由于我们排了序,所以不需要第二维的定义。
对了,要处理一下边权相等的情况,这个可以拿一个tmp去记录一下
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e5+7;
pair<int,pair<int,int> >E[maxn];
int dp[maxn];
int tmp[maxn];
void init()
{
memset(dp,0,sizeof(dp));
memset(tmp,0,sizeof(tmp));
memset(E,0,sizeof(E));
}
void solve()
{
init();
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
E[i]=make_pair(z,make_pair(x,y));
}
sort(E+1,E+1+m);
int j = 1;
for(int i=1;i<=m;i++)
{
if(i<=m-1&&E[i+1].first==E[i].first)
continue;
for(int k=j;k<=i;k++)
tmp[E[k].second.second]=max(tmp[E[k].second.second],dp[E[k].second.first]+1);
for(int k=j;k<=i;k++)
dp[E[k].second.second]=tmp[E[k].second.second];
j=i+1;
}
int ans = 0;
for(int i=1;i<=n;i++)
ans = max(ans,dp[i]);
cout<<ans<<endl;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)solve();
return 0;
}